Skip to content

Commit

Permalink
fix #1: normalization of imp/exp configuration maps
Browse files Browse the repository at this point in the history
It is now possible to give explicitely a dump file name and a log file name. The file prefix and log type are used to generate a filename if the value is not present in the map.

Signed-off-by: Stanislas Nanchen <stan@hood.ch>
  • Loading branch information
stanislas committed Jun 12, 2015
1 parent 16d8b6b commit 0ab8022
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 14 deletions.
38 changes: 32 additions & 6 deletions src/clojure/li/elmnt/datapump/impl/common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,53 @@
:imp-log-file "dbms_datapump.KU$_FILE_TYPE_LOG_FILE"
:dump-file "dbms_datapump.KU$_FILE_TYPE_DUMP_FILE"))

(defn render-add-file [directory file-type file-basename reuse-dump-file]
(defn derive-file-name
"The function `derive-file-name` computes the definitive file name for given file type. The file name is
either already defined or it is computed from a prefix and a suffix based on its type. If neither file
name nor the pair file prefix and file type are defined, an error is thrown."
[file-name file-prefix file-type]
{:pre [(not (and (nil? file-name) (or (nil? file-prefix) (nil? file-type))))]}
(if (nil? file-name)
(str file-prefix (file-type-suffix file-type))
file-name))

(defn derive-file-names
"The function `derive-file-names` derive the dump file name and the log file name for the given operation."
[{:keys [dump-file log-file file-prefix] :as config} operation]
(assoc config :dump-file (derive-file-name dump-file file-prefix :dump-file)
:log-file (derive-file-name log-file file-prefix (log-file-type operation))))

(defn normalize
"The function `normalize` takes a configuration map and a schema and will apply normalizing functions
to derive obligatory values from optional values when applicable.
The triadic version will call the supplied function to the normalize configuration map."
([data operation]
(derive-file-names data operation))
([data operation f]
(let [data (normalize data operation)]
(f data))))

(defn render-add-file [directory file-type file-name reuse-dump-file]
(str "dbms_datapump.add_file("
"handle => handle, "
"filename => '" (str file-basename (file-type-suffix file-type)) "', "
"filename => '" file-name "', "
"directory => '" directory "', "
"filetype => " (file-type-filetype file-type)
(when (= file-type :dump-file) (str ", reusefile => " (if reuse-dump-file 1 0)))
");"
))

(defn render-header [datapump-operation {:keys [remote-link file-prefix directory reuse-dump-file]}]
(defn render-header [datapump-operation {:keys [remote-link log-file dump-file directory reuse-dump-file]}]
(str/join "\n"
["declare"
"handle number;"
"job_state varchar2(50);"
"begin"
(str "handle := dbms_datapump.open('" (render-datapump-operation datapump-operation) "', 'SCHEMA'"
(if (nil? remote-link) "" (str ", remote_link => " (single-quote remote-link))) ");")
(render-add-file directory :dump-file file-prefix reuse-dump-file)
(render-add-file directory (log-file-type datapump-operation) file-prefix reuse-dump-file)
(render-add-file directory :dump-file dump-file reuse-dump-file)
(render-add-file directory (log-file-type datapump-operation) log-file reuse-dump-file)
]))

(defn render-footer [sqlplus?]
Expand Down Expand Up @@ -106,7 +133,6 @@
;; if we come here, we have the guarantee of a single schema mode. see validate.
(render-metadata-filter (get schemas (-> schemas keys first)) {:filter-types [:include-tables :exclude-tables]
:object-type "TABLES"}))

(defn render-object-type-metadatafilter
[data]
(render-metadata-filter data {:filter-types [:include-object-types :exclude-object-types]}))
Expand Down
16 changes: 12 additions & 4 deletions src/clojure/li/elmnt/datapump/impl/expdp.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
(s/optional-key :exclude-tables) #{s/Str}
(s/optional-key :subquery-filters) {s/Str s/Str}
(s/optional-key :partition-list-filters) {s/Str [s/Str]}}}
:file-prefix s/Str
:directory s/Str
:dump-file s/Str
:log-file s/Str
(s/optional-key :file-prefix) s/Str
(s/optional-key :reuse-dump-file) s/Bool
(s/optional-key :sqlplus?) s/Bool
(s/optional-key :exclude-object-types) [s/Str]
Expand Down Expand Up @@ -60,7 +62,7 @@
(throw (IllegalArgumentException. ":tables filter is allowed only on single schema exp-data.")))
exp-data))

(s/defn render-exp-script
(s/defn render-exp-script-strict
([exp-data :- ExpData]
(validate exp-data)
(str/join "\n"
Expand All @@ -70,9 +72,15 @@
(str/join "\n" (:custom exp-data))
(c/render-footer (get exp-data :sqlplus? true))]))
([file exp-data :- ExpData]
(let [script (render-exp-script exp-data)]
(let [script (render-exp-script-strict exp-data)]
(spit file script))))

(defn render-exp-script
([exp-data]
(c/normalize exp-data :export render-exp-script-strict))
([file exp-data]
(c/normalize exp-data :export (partial render-exp-script-strict file))))

(comment
(def input {:schemas {"SIMON1"
{:include-tables #{"CUSTOMER" "LC_CONFIGURATION"}
Expand All @@ -83,7 +91,7 @@
:partition-list-filters {"T1" ["SYS1" "SYS2"]
"T2" ["SYS3" "SYS4"]}}}
:exclude-object-types ["VIEW"]
:file-prefix "simon1"
:file-prefix "simon1"
:directory "DATA_PUMP_DIR"
:reuse-dump-file true})

Expand Down
14 changes: 10 additions & 4 deletions src/clojure/li/elmnt/datapump/impl/impdp.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
(def ImpData
{:schemas {s/Str {(s/optional-key :remap-to) s/Str}}
:tablespaces-remap {s/Str s/Str}
:file-prefix s/Str
:file-prefix s/Str
(s/optional-key :sqlplus?) s/Bool
(s/optional-key :exclude-object-types) [s/Str]
(s/optional-key :include-object-types) [s/Str]
Expand Down Expand Up @@ -37,7 +37,7 @@
(str/join "\n"
(map #(render-remap :remap-tablespace %) tablespaces-remap)))

(s/defn render-imp-script
(s/defn render-imp-script-strict
([imp-data :- ImpData]
(str/join "\n"
[(c/render-header :import imp-data)
Expand All @@ -47,11 +47,17 @@
(str/join "\n" (:custom imp-data))
(c/render-footer (get imp-data :sqlplus? true))]))
([file imp-data :- ImpData]
(spit file (render-imp-script imp-data))))
(spit file (render-imp-script-strict imp-data))))

(defn render-imp-script
([imp-data]
(c/normalize imp-data :import render-imp-script-strict))
([file imp-data]
(c/normalize imp-data :import (partial render-imp-script-strict file))))

(comment
(def imp-data {:directory "DATA_PUMP_DIR"
:file-prefix "arims_2015_3_20"
:file-prefix "arims_2015_3_20"
:tablespaces-remap {"SIMON1_DATA" "STAN1_DATA"}
:schemas {"SIMON1" {:remap-to "STAN1"}}})

Expand Down
42 changes: 42 additions & 0 deletions test/clojure/li/elmnt/datapump/impl/common_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
(ns li.elmnt.datapump.impl.common-test
(:require
[li.elmnt.datapump.impl.common :as c]
[midje.sweet :refer :all]))

(defn statement [test-fn statement]
(str (-> test-fn meta :name) " " statement))

(facts "derive-file-name trustful"
(c/derive-file-name "filename.log" nil nil) => "filename.log"
(c/derive-file-name "filename.log" "filename" :dump-file) => "filename.log"
(c/derive-file-name nil "filename" :dump-file) => "filename.dump")

(def error (throws AssertionError))

(facts "derive-file-name defensive"
(c/derive-file-name nil nil :dump-file) => error
(c/derive-file-name nil "filename" nil) => error
(c/derive-file-name nil nil nil) => error)

(defn derive-file-names-trustful [test-fn]
(facts (statement test-fn "trustful")
(test-fn {:file-prefix "file"} :export)
=> (contains {:log-file "file_exp.log" :dump-file "file.dump"})
(test-fn {:file-prefix "file" :log-file "logfile"} :export)
=> (contains {:log-file "logfile" :dump-file "file.dump"})
(test-fn {:file-prefix "file" :dump-file "dumpfile"} :export)
=> (contains {:log-file "file_exp.log" :dump-file "dumpfile"})
(test-fn {:file-prefix "file" :dump-file "dumpfile" :log-file "logfile"} :export)
=> (contains {:log-file "logfile" :dump-file "dumpfile"})))

(derive-file-names-trustful #'c/derive-file-names)
(derive-file-names-trustful #'c/normalize)

(defn derive-file-names-defensive [test-fn]
(facts (statement test-fn "defensive")
(test-fn {} :export) => error
(test-fn {:log-file "logfile.log"} :export) => error
(test-fn {:dump-file "dumpfile.dump"} :export) => error))

(derive-file-names-defensive #'c/derive-file-names)
(derive-file-names-defensive #'c/normalize)

0 comments on commit 0ab8022

Please sign in to comment.