Skip to content
sdegutis edited this page Nov 15, 2012 · 17 revisions

Migrations

Migrations consist of a map of two one-argument functions, :up and :down, and a unique identifier, :id.

Here's an example of one that modifies an in-memory atom stored in (:data db):

(def add-dog
  {:id "add-dog"
   :up   (fn [db] (swap! (:data db) conj :dog))
   :down (fn [db] (swap! (:data db) disj :dog))})

You can apply a migration to a database using the migrate function, and remove a migration using rollback. Ragtime will maintain a list of applied migrations which you can access with the applied-migrations function:

(migrate db add-dog)

(applied-migrations db)
=> [add-dog]

(rollback db add-dog)

(applied-migrations db)
=> []

Databases

The database itself needs to be a type that implements the ragtime.core/Migratable protocol. If we wanted an in-memory database that wrapped an atom, we might implement it as a record:

(defrecord MemoryDatabase [data]
  (add-migration-id [_ id]
    (swap! data update-in [:migrations] conj id))
  (remove-migration-id [_ id]
    (swap! data update-in [:migrations]
           (vec (remove (partial = id) %))))
  (applied-migration-ids [_]
    (seq (:migrations @data))))

(defn memory-database []
  (MemoryDatabase. (atom {:migrations []})))

It's important that applied-migration-ids maintains the order migrations were applied in, which is why we're using a vector in this example.

The ragtime.sql library includes a SqlDatabase record that can be used to wrap a database connection map. For instance:

#ragtime.sql.database.SqlDatabase{
  :classname "org.h2.Driver"
  :subprotocol "h2"
  :subname "mem:test_db"
  :user "test"
  :password ""}

Connections

The ragtime.core/connection multimethod is a way of creating a database from a URL. It dispatches off the URL scheme, so if the URL was "jdbc:h2:mem:test_db", it would dispatch off "jdbc".

The ragtime.sql library includes an implementation of the connection multimethod that handles JDBC URLs like the one above. To use it, require ragtime.sql.database:

(use 'ragtime.core)
(require 'ragtime.sql.database)

(connection "jdbc:h2:mem:test_db")
;; The above line is equivalent to the previous SqlDatabase example
Clone this wiki locally