Shantanu Kumar avatar Shantanu Kumar committed db41939

add `diff` command

Comments (0)

Files changed (4)

 - [TODO] Other Clj-Liquibase commands: Reverse-engineer schema
+## 0.3 / 2011-Jul-??
+* Update to Clj-Liquibase 0.3
+* Clj-Liquibase command: Diff (regular, not diffChangelog)
 ## 0.2 / 2011-Apr-05
 - Pick up var that defines changelog (Clj-Liquibase) from application sources
-(defproject org.bituf/lein-lb "0.2"
+(defproject org.bituf/lein-lb "0.3-SNAPSHOT"
   :description "Leiningen plugin for Clj-Liquibase:"
   :url         ""
-  :dependencies [[org.bituf/clj-liquibase "0.2"] ; pulls in clj-miscutil 0.3
+  :dependencies [[org.bituf/clj-liquibase "0.3-SNAPSHOT"] ; pulls in clj-miscutil 0.3
                  [org.bituf/clj-dbcp      "0.5"]]
-  :dev-dependencies [[org.clojure/clojure "1.2.0"]]
+  :dev-dependencies [[org.clojure/clojure "1.3.0-beta1"]]
   :eval-in-leiningen true)


 rollback   - Rolls back database
 tag        - Tags the database
 dbdoc      - Generates documentation for database/changelogs
+diff       - Reports differences between two database instances
 For help on individual command, append with `--help`, e.g.:
 lein lb update --help
                                          (into acc
                                            {(get rev-opts (as-string opt)) nil}))
                                        (if (contains? acc :more)
-                                         (into acc :more (cons arg (:more acc)))
                                          {:more [arg]})))
                      (if (some #(= arg %) ["--help" "-h" "/?"])
                        (do (print-usage cmd-prefix spec)
                          {:help nil})
-                       (throw (IllegalArgumentException.
-                                (str "Illegal option: " arg))))))]
+                       (into acc :more (cons arg (:more acc))))
+                     (throw (IllegalArgumentException.
+                              (str "Illegal option: " arg)))))]
     (let [opt-map   (reduce get-opts {} args)
           with-arg? (fn []
                       (every? (fn [row]
             (lb/generate-doc changelog out-dir (ctx-list contexts))))))))
+(defn parse-diff-args
+  "Parse arguments for `diff` command."
+  [& args]
+  (parse-opts "lein lb diff"
+    args
+    ["Clj-DBCP profile name (default if unspecified)" :opt-arg  :profile     :p]
+    ["Reference Clj-DBCP profile name"                :with-arg :ref-profile :r]))
+(defn diff
+  "Report differences between two database instances"
+  [& args]
+  (let [opt (apply parse-diff-args args)]
+    (when-not (contains? opt :help)
+      (let [profile     (:profile     opt)
+            ref-profile (:ref-profile opt)]
+        ;; begin with reference DB profile
+        (sp/with-dbspec
+          (cp/db-spec (make-datasource ref-profile))
+          (sp/with-connection
+            sp/*dbspec*
+            (let [ref-db (lb/make-db-instance (:connection sp/*dbspec*))]
+              ;; go on to target DB profile
+              (sp/with-dbspec (cp/db-spec (make-datasource profile))
+                              (lb/with-lb
+                                (lb/diff ref-db))))))))))
 ;; ----- Leiningen plugin command -----
 (defn lb
+  "Entry point for the Lein-LB plugin."
   [project & args]
   (let [argc (count args)
         cmd  (or (first args) "")]
       "version"    (println (format "Lein-LB version %s"
                               (apply str (interpose "." version))))
       "dbcp-props" (println (slurp (io/resource "")))
-      "update"     (eip-fn project update (rest args)
-                     [:changelog :profile :chs-count :contexts :sql-only])
+      "update"     (eip-fn project update   (rest args)
+                           [:changelog :profile :chs-count :contexts :sql-only])
       "rollback"   (eip-fn project rollback (rest args)
-                     [:changelog :profile :chs-count :tag :date :contexts :sql-only])
-      "tag"        (eip-fn project tag (rest args)
-                     [:profile :tag])
-      "dbdoc"      (eip-fn project dbdoc (rest args)
-                     [:changelog :profile :output-dir :contexts])
+                           [:changelog :profile :chs-count :tag :date :contexts :sql-only])
+      "tag"        (eip-fn project tag      (rest args)
+                           [:profile :tag])
+      "dbdoc"      (eip-fn project dbdoc    (rest args)
+                           [:changelog :profile :output-dir :contexts])
+      "diff"       (eip-fn project diff     (rest args)
+                           [:profile :ref-profile])
         (println (format "Invalid command: %s" cmd))
         (lb project "help")))))


                  "-ofoo"))                    "all combined (short version)")
       (is (thrown? IllegalArgumentException (ll/parse-dbdoc-args "--bad")))
       (is (= {:help nil} (ll/parse-dbdoc-args "--help"))))))
+(deftest test-diff-args
+  (testing "diff args"
+           (let [a {:profile "pp" :ref-profile "rr"}]
+             (is (= a (ll/parse-diff-args "--profile=pp" "--ref-profile=rr")) "full")
+             (is (= a (ll/parse-diff-args "-ppp"         "-rrr"))             "short"))
+           (let [a {:ref-profile "rr"}]
+             (is (= a (ll/parse-diff-args "--ref-profile=rr")) "full w/o profile")
+             (is (= a (ll/parse-diff-args "-rrr"))             "short w/o profile"))
+           (is (= {:help nil} (ll/parse-diff-args "--help")))))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.