If you try to build a standalone application which uses Crane you will probably run into problems when the compiler tries to dump the lisp image. It will complain about open database connections.

Crane is an ORM (object relational mapping) library. It is mostly used in server-side software but it is also useful for desktop software because it supports SQLite.

There is a bug in Crane which requires an open database connection before tables can be defined. This is not a big problem when the application is run from source code, i.e. server-side software. However, it is a problem when you are building a binary. The lisp image can not be dumped if there are open streams, file descriptors or database connections.

This situation takes a bit of effort to work around. You need a database connection just to compile the application. You then need to close it properly before the image can be dumped. All for a database connection which will never be used.

A procedure which meets the requirements for image dumping and enables proper initialization at application startup is:

  1. Put the setup form inside a function.
  2. Call the setup function from the top-level.
  3. Define all tables.
  4. Close the connection at the top-level.

The example below implements the necessary steps.

(defun prepare-database ()
  (crane:setup :migrations-directory #P"/path/to/migrations/"
               :databases `(:main
                            (:type :sqlite3 :name #P"/path/to/db")))

  ;; Connecting opens / creates the database. Required for table
  ;; definition.
  (crane:connect))

;; Database must be open at compile time. Close again after table
;; definitions.
(prepare-database)

;; Table definitions
(deftable ... )

;; Initialize at application start.
(defun initialize ()
  (prepare-database))

;; Application entry point
(defun main ()
  (initialize)
  (program-logic))

;; Disconnect from DB for image creation. Must be last form in the file.
(crane:disconnect)