Created
February 26, 2010 15:09
-
-
Save RickMoynihan/315787 to your computer and use it in GitHub Desktop.
Rails like Database Migrations in Clojure... Using clojure.contrib.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def migrations (sorted-map | |
;; Migrations are numbered by integer values to explicitly document them | |
1 { | |
:doc "Foo Table" | |
:up (fn [] | |
(create-table | |
:Foo | |
[:id :int "PRIMARY KEY" "NOT NULL GENERATED ALWAYS AS IDENTITY"] | |
; store a JSON blob in here for the screening record | |
[:logdata "CLOB(4k)"])) | |
:down #(drop-table :Foo) | |
} | |
2 { | |
:doc "Bar Table" | |
:up #(create-table :BarTable | |
[:id :int "NOT NULL UNIQUE"] | |
[:blah "VARCHAR(20)"] | |
[:status "VARCHAR(10)"] | |
[:comments "VARCHAR(255)"] | |
[:recorded_at "TIMESTAMP"]) | |
:down #(drop-table :BarTable) | |
})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; The use and distribution terms for this software are covered by the | |
;;; Eclipse Public License 1.0, which can be found at | |
;;; | |
;;; http://opensource.org/licenses/eclipse-1.0.php | |
;;; | |
;;; By using this software in any fashion, you are agreeing to be bound | |
;;; by the terms of this license. You must not remove this notice, or any | |
;;; other, from this software. | |
(ns railsy.migrations | |
(:use (clojure.contrib | |
[sql :only (insert-values | |
delete-rows | |
do-commands | |
with-connection | |
create-table | |
drop-table | |
transaction | |
with-query-results)] | |
[logging :only (info warn)] | |
[core :only (.?.)] | |
[java-utils :only (as-str)])) | |
(:import (java.sql SQLException))) | |
(def *application-db* {:classname "org.apache.derby.jdbc.EmbeddedDriver" | |
:subprotocol "derby" | |
:subname "MyDB" | |
:create true | |
}) | |
(defn- execute-migration [direction] | |
(fn [[version { migration-fn direction | |
doc :doc }]] | |
(info (str (direction {:up "Applying migration " | |
:down "Undoing migration "}) version " " doc)) | |
(transaction | |
(migration-fn) | |
(if (= :up direction) | |
(insert-values :SchemaVersion | |
[:version] | |
[version]) | |
(delete-rows :SchemaVersion ["version=?" version]))))) | |
(defn- run-migrations [direction from to] | |
"Run the specified migrations on the database" | |
(dorun (map (execute-migration direction) (if (= :up direction) | |
(take (- to from) (nthnext migrations from)) | |
(reverse (take (- from to) (nthnext migrations to))))))) | |
(defn- create-schema-table-if-needed [direction to] | |
(try | |
(info "Attempting to create SchemaVersion table") | |
(create-table :SchemaVersion [:version :int "NOT NULL UNIQUE"]) | |
(info "No SchemaVersion table exists - first run installing migrations") | |
(try | |
(run-migrations direction 0 to) | |
(catch Exception ex | |
(warn "Error running migrations: " ex))) | |
(catch Exception e | |
(when-not (= java.sql.BatchUpdateException (.?. e getCause getClass)) | |
(throw (SQLException. "Unknown error whilst creating SchemaVersion table" e)))))) | |
(defn migrate | |
"Pass it :up or :down and a version to migrate to. If no arguments | |
are supplied we assume application of all migrations." | |
([] (migrate :up (count migrations))) | |
([direction to] | |
(with-connection *application-db* | |
(when (= :up direction) | |
(create-schema-table-if-needed direction to)) | |
(let [current-version (or (with-query-results rs | |
["SELECT MAX(version) as version FROM SchemaVersion"] | |
(:version (first rs))) | |
0)] | |
(run-migrations direction current-version to))))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Let me know if you do, good luck!