forked from sharetribe/dumpr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
table_schema.clj
66 lines (59 loc) · 2.05 KB
/
table_schema.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(ns dumpa.table-schema
"Parsing and manipulating the table schema"
(:require [schema.core :as s]
[clojure.core.async :as async :refer [chan]]
[dumpa.query :as query]))
(def Col
{:name s/Keyword
:type s/Keyword
:character-set (s/maybe s/Str)})
(def TableSchema
"A schema for parsed table schema"
{:table s/Keyword
:primary-key (s/maybe s/Keyword)
:id-fn (s/pred ifn?)
:cols [Col]}
)
(def TableSpec
"A partial schema specification for a table with optional id-fn."
{:table s/Keyword
(s/optional-key :id-fn) (s/maybe (s/pred ifn?))})
(defn- parse-table-cols
"Parse the cols column metadata into a table schema presentation."
[cols]
(reduce
(fn [schema {:keys [column_name data_type column_key character_set_name]}]
(let [name (keyword column_name)
type (keyword data_type)]
(if (= column_key "PRI")
(-> schema
(update-in [:cols] conj {:name name :type type :character-set character_set_name})
(assoc :primary-key name))
(-> schema
(update-in [:cols] conj {:name name :type type :character-set character_set_name})))))
{:primary-key nil :cols []}
cols))
(s/defn load-schema :- TableSchema
[db-spec :- s/Any
db :- s/Str
table-spec :- TableSpec]
(let [{:keys [table id-fn]} table-spec
schema-info (-> (query/fetch-table-cols db-spec db (name table))
parse-table-cols)]
(-> schema-info
(assoc :table table)
(assoc :id-fn (or id-fn
(:primary-key schema-info))))))
(s/defn ->table-spec :- TableSpec
[table :- s/Keyword
id-fns :- {s/Keyword clojure.lang.IFn}]
{:table table :id-fn (id-fns table)})
(defn load-and-parse-schemas
[tables db-spec db id-fns]
(let [out (chan)
xform (comp
(map #(->table-spec % id-fns))
(map #(s/with-fn-validation (load-schema db-spec db %))))
schemas (transduce xform conj [] tables)]
(async/onto-chan out schemas)
out))