From 0a2fdc8cc3db6b2a50c35016c0fce9491e37d6a8 Mon Sep 17 00:00:00 2001 From: "Michael S. Klishin" Date: Tue, 19 Jun 2012 12:18:43 +0400 Subject: [PATCH] Ragtime migrations adapter --- ChangeLog.md | 19 ++++++++++++++++ project.clj | 3 ++- src/clojure/monger/ragtime.clj | 34 ++++++++++++++++++++++++++++ test/monger/test/fixtures.clj | 1 + test/monger/test/ragtime_test.clj | 37 +++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/clojure/monger/ragtime.clj create mode 100644 test/monger/test/ragtime_test.clj diff --git a/ChangeLog.md b/ChangeLog.md index c5a3002..891cded 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,24 @@ ## Changes between 1.0.0-rc1 and 1.0.0-rc2 +### Ragtime integration + +Monger now provides an adapter for [Ragtime, a generic Clojure library for data migrations](https://github.com/weavejester/ragtime) (evolutions). + +It is in the `monger.ragtime` namespace. To use Ragtime with Monger, you need to add dependencies +on both Ragtime core and Monger to your project. An example with Leiningen: + +``` clojure +:dependencies [[org.clojure/clojure "1.4.0"] + [com.novemberain/monger "1.0.0-rc2"] + [ragtime/ragtime.core "0.2.0"]] +``` + +Then require `monger.ragtime` and use Ragtime as usual, passing it a database instance +you get via `monger.core/get-db`. + +Monger will persist information about migrations using the `FSYNC_SAFE` write concern. + + ### Query DSL no longer seq()s the cursor Query DSL will no longer apply `clojure.core/seq` to the underlying cursor, thus guaranteeing to return an empty diff --git a/project.clj b/project.clj index 1ae3c4e..428c7f0 100644 --- a/project.clj +++ b/project.clj @@ -5,7 +5,8 @@ :dependencies [[org.clojure/clojure "1.3.0"] [org.mongodb/mongo-java-driver "2.7.3"] [com.novemberain/validateur "1.1.0"] - [clojurewerkz/support "0.5.0"]] + [clojurewerkz/support "0.5.0"] + [ragtime/ragtime.core "0.2.0" :exclusions [org.clojure/clojure]]] :test-selectors {:default (fn [m] (and (not (:performance m)) (not (:edge-features m)))) diff --git a/src/clojure/monger/ragtime.clj b/src/clojure/monger/ragtime.clj new file mode 100644 index 0000000..857c7f1 --- /dev/null +++ b/src/clojure/monger/ragtime.clj @@ -0,0 +1,34 @@ +(ns monger.ragtime + (:refer-clojure :exclude [find sort]) + (:require [ragtime.core :as ragtime] + [monger.core :as mg] + [monger.collection :as mc]) + (:use [monger.query :only [with-collection find sort]]) + (:import java.util.Date + [com.mongodb DB WriteConcern])) + + +(def ^{:const true} + migrations-collection "meta.migrations") + + + +(extend-type com.mongodb.DB + ragtime/Migratable + (add-migration-id [db id] + (mc/insert db migrations-collection {:_id id :created_at (Date.)} WriteConcern/FSYNC_SAFE)) + (remove-migration-id [db id] + (mc/remove-by-id db migrations-collection id)) + (applied-migration-ids [db] + (mg/with-db db + (let [xs (with-collection migrations-collection + (find {}) + (sort {:created_at 1}))] + (set (map :_id xs)))))) + + +(defn flush-migrations! + "REMOVES all the information about previously performed migrations" + [db] + (mg/with-db db + (mc/remove migrations-collection))) \ No newline at end of file diff --git a/test/monger/test/fixtures.clj b/test/monger/test/fixtures.clj index bf6dfe5..081b843 100644 --- a/test/monger/test/fixtures.clj +++ b/test/monger/test/fixtures.clj @@ -17,3 +17,4 @@ (defcleaner cached "cached") +(defcleaner migrations "meta.migrations") diff --git a/test/monger/test/ragtime_test.clj b/test/monger/test/ragtime_test.clj new file mode 100644 index 0000000..c6496eb --- /dev/null +++ b/test/monger/test/ragtime_test.clj @@ -0,0 +1,37 @@ +(set! *warn-on-reflection* true) + +(ns monger.test.ragtime-test + (:require [monger.core :as mg] + [monger.collection :as mc] + [monger.test.helper :as helper] + monger.ragtime) + (:use clojure.test + [monger.test.fixtures :only [purge-migrations]] + ragtime.core)) + + +(helper/connect!) + +(use-fixtures :each purge-migrations) + + +(deftest test-add-migration-id + (let [db (mg/get-db "monger-test") + coll "meta.migrations" + key "1"] + (is (not (mc/any? db coll {:_id key}))) + (is (not (contains? (applied-migration-ids db) key))) + (add-migration-id db key) + (is (mc/any? db coll {:_id key})) + (is (contains? (applied-migration-ids db) key)))) + + +(deftest test-remove-migration-id + (let [db (mg/get-db "monger-test") + coll "meta.migrations" + key "1"] + (add-migration-id db key) + (is (mc/any? db coll {:_id key})) + (is (contains? (applied-migration-ids db) key)) + (remove-migration-id db key) + (is (not (contains? (applied-migration-ids db) key)))))