rlm@0
|
1 (ns coderloop.scientist-sql
|
rlm@0
|
2 (:refer-clojure :only [])
|
rlm@0
|
3 (:require rlm.ns-rlm rlm.light-base))
|
rlm@0
|
4 (rlm.ns-rlm/ns-clone rlm.light-base)
|
rlm@0
|
5
|
rlm@0
|
6
|
rlm@0
|
7 (use 'clojure.contrib.sql) ;;' satisfy prettify
|
rlm@0
|
8 (import 'org.gjt.mm.mysql.Driver)
|
rlm@0
|
9 (use 'clojure.contrib.sql)
|
rlm@0
|
10 (import '[org.joda.time LocalDate ])
|
rlm@0
|
11 (undef distinct case compile drop take sort)
|
rlm@0
|
12 (use 'clojureql.core)
|
rlm@0
|
13 (import 'org.joda.time.DateMidnight)
|
rlm@0
|
14 (import 'java.io.File)
|
rlm@0
|
15 (use '[clojure.java.io :only [copy]])
|
rlm@0
|
16 (use '[clojure.contrib.shell-out :only [sh]])
|
rlm@0
|
17 (use '[clojure.string :only [split]])
|
rlm@0
|
18 (use '[coderloop [utils :only [md5]]])
|
rlm@0
|
19
|
rlm@0
|
20 (defn sql-date [date]
|
rlm@0
|
21 "Convert any Joda-readable date object (including a string) to a java.sql.Date"
|
rlm@0
|
22 (java.sql.Date. (.. (LocalDate. date) toDateMidnight toInstant getMillis)))
|
rlm@0
|
23
|
rlm@0
|
24 (def *port* 3306)
|
rlm@0
|
25
|
rlm@0
|
26 (def *host* "localhost")
|
rlm@0
|
27
|
rlm@0
|
28 (def *db-host* "localhost")
|
rlm@0
|
29
|
rlm@0
|
30 (def *db-name* "clojure_rlm")
|
rlm@0
|
31
|
rlm@0
|
32 (def *db* {:classname "com.mysql.jdbc.Driver"
|
rlm@0
|
33 :subprotocol "mysql"
|
rlm@0
|
34 :subname (str "//" *db-host* ":" *port* "/" *db-name*)
|
rlm@0
|
35 :user "root"
|
rlm@0
|
36 :password "sql1005025"})
|
rlm@0
|
37
|
rlm@0
|
38 (def *db2* {:classname "com.mysql.jdbc.Driver"
|
rlm@0
|
39 :subprotocol "mysql"
|
rlm@0
|
40 :subname (str "//" *db-host* ":" *port* "/" "test_rlm")
|
rlm@0
|
41 :user "root"
|
rlm@0
|
42 :password "sql1005025"})
|
rlm@0
|
43
|
rlm@0
|
44
|
rlm@0
|
45 (def databases [:essay_scientists :scientists :ideas :scientist_whereabouts])
|
rlm@0
|
46
|
rlm@0
|
47 (defmacro no-exceptions
|
rlm@0
|
48 "Sweet relief like I never knew."
|
rlm@0
|
49 [& forms]
|
rlm@0
|
50 `(try ~@forms (catch Exception e# (.printStackTrace e#))))
|
rlm@0
|
51
|
rlm@0
|
52
|
rlm@0
|
53 (defn make-essay-scientists []
|
rlm@0
|
54 (with-connection
|
rlm@0
|
55 *db2*
|
rlm@0
|
56 (no-exceptions (drop-table :essay_scientists))
|
rlm@0
|
57 (create-table
|
rlm@0
|
58 :essay_scientists
|
rlm@0
|
59 [:id "integer"]
|
rlm@0
|
60 [:name "varchar(255)"]
|
rlm@0
|
61 [:surname "varchar(255)"])
|
rlm@0
|
62 (insert-rows :essay_scientists
|
rlm@0
|
63 [1 "Isaac" "Newton"]
|
rlm@0
|
64 [2 "Albert" "Einstein"])))
|
rlm@0
|
65
|
rlm@0
|
66 (defn make-scientists []
|
rlm@0
|
67 (with-connection
|
rlm@0
|
68 *db2*
|
rlm@0
|
69 (no-exceptions (drop-table :scientists))
|
rlm@0
|
70 (create-table
|
rlm@0
|
71 :scientists
|
rlm@0
|
72 [:name "varchar(255)"]
|
rlm@0
|
73 [:surname "varchar(255)"]
|
rlm@0
|
74 [:birth_place "varchar(255)"]
|
rlm@0
|
75 [:death_place "varchar(255)"]
|
rlm@0
|
76 [:birth_date "date"]
|
rlm@0
|
77 [:death_date "date"])
|
rlm@0
|
78 (insert-rows
|
rlm@0
|
79 :scientists
|
rlm@0
|
80 ["Albert" "Einstein" "Ulm" "Princeton" "1879-3-14" "1955-4-18"]
|
rlm@0
|
81 ["Galileo" "Galilei" "Pisa" "Arcetri" "1564-2-15" "1645-1-8"]
|
rlm@0
|
82 ["Enrico" "Fermi" "Roma" "Chicago" "1901-9-29" "1954-9-28"]
|
rlm@0
|
83 ["Isaac" "Newton" "Woolsthorpe-by-Colsterworth" "London" "1643-1-4" "1727-3-31"]
|
rlm@0
|
84 ["Marx" "Planck" "Kiel" "Göttingen" "1858-4-23" "1947-10-4"])))
|
rlm@0
|
85
|
rlm@0
|
86
|
rlm@0
|
87 (defn make-scientist-whereabouts []
|
rlm@0
|
88 (with-connection *db2*
|
rlm@0
|
89 (no-exceptions (drop-table :scientist_whereabouts ))
|
rlm@0
|
90 (create-table
|
rlm@0
|
91 :scientist_whereabouts
|
rlm@0
|
92 [:name "varchar(255)"]
|
rlm@0
|
93 [:surname "varchar(255)"]
|
rlm@0
|
94 [:country "varchar(255)"]
|
rlm@0
|
95 [:immigration_date "date"]
|
rlm@0
|
96 [:emigration_date "date"])
|
rlm@0
|
97 (insert-rows
|
rlm@0
|
98 :scientist_whereabouts
|
rlm@0
|
99 ["Galileo" "Galilei" "France" "1602-2-18" "1604-4-20"]
|
rlm@0
|
100 ["Albert" "Einstein" "Uk" "1901-10-22" "1905-5-4"]
|
rlm@0
|
101 ["Marx" "Planck" "Denmark" "1901-1-31" "1945-7-4"]
|
rlm@0
|
102 ["Albert" "Einstein" "France" "1908-11-7" "1930-3-12"]
|
rlm@0
|
103 ["Enrico" "Fermi" "Us" "1924-12-19" "1954-9-28"]
|
rlm@0
|
104 ["Isaac" "Newton" "Uk" "1688-9-8" "1690-7-12"]
|
rlm@0
|
105 ["Albert" "Einstein" "US" "1935-10-22" "1955-4-18"]
|
rlm@0
|
106 ["Isaac" "Newton" "Germany" "1690-9-28" "1705-4-6"])))
|
rlm@0
|
107
|
rlm@0
|
108
|
rlm@0
|
109 (defn make-ideas []
|
rlm@0
|
110 (with-connection *db2*
|
rlm@0
|
111 (no-exceptions (drop-table :ideas))
|
rlm@0
|
112 (create-table
|
rlm@0
|
113 :ideas
|
rlm@0
|
114 [:name "varchar(255)"]
|
rlm@0
|
115 [:surname "varchar(255)"]
|
rlm@0
|
116 [:idea "varchar(255)"])
|
rlm@0
|
117 (insert-rows
|
rlm@0
|
118 :ideas
|
rlm@0
|
119 ["Albert" "Einstein" "Theory of relativity (general)"]
|
rlm@0
|
120 ["Enrico" "Fermi" "First nuclear reactor"]
|
rlm@0
|
121 ["Albert" "Einstein" "Photoelectric effect"]
|
rlm@0
|
122 ["Isaac" "Newton" "Gravity"]
|
rlm@0
|
123 ["Galileo" "Galilei" "Telescope"]
|
rlm@0
|
124 ["Albert" "Einstein" "Theory of relativity (special)"]
|
rlm@0
|
125 ["Isaac" "Newton" "Dark matter"])))
|
rlm@0
|
126
|
rlm@0
|
127 (defn clear-tables []
|
rlm@0
|
128 (with-connection *db2* (dorun (map drop-table databases))))
|
rlm@0
|
129
|
rlm@0
|
130 (defn fill-tables []
|
rlm@0
|
131 (make-ideas)
|
rlm@0
|
132 (make-essay-scientists)
|
rlm@0
|
133 (make-scientist-whereabouts)
|
rlm@0
|
134 (make-scientists))
|
rlm@0
|
135
|
rlm@0
|
136 (defn make-empty-tables []
|
rlm@0
|
137 (with-connection *db2*
|
rlm@0
|
138 (create-table
|
rlm@0
|
139 :ideas
|
rlm@0
|
140 [:name "varchar(255)"]
|
rlm@0
|
141 [:surname "varchar(255)"]
|
rlm@0
|
142 [:idea "varchar(255)"])
|
rlm@0
|
143 (create-table
|
rlm@0
|
144 :scientist_whereabouts
|
rlm@0
|
145 [:name "varchar(255)"]
|
rlm@0
|
146 [:surname "varchar(255)"]
|
rlm@0
|
147 [:country "varchar(255)"]
|
rlm@0
|
148 [:immigration_date "date"]
|
rlm@0
|
149 [:emigration_date "date"])
|
rlm@0
|
150 (create-table
|
rlm@0
|
151 :scientists
|
rlm@0
|
152 [:name "varchar(255)"]
|
rlm@0
|
153 [:surname "varchar(255)"]
|
rlm@0
|
154 [:birth_place "varchar(255)"]
|
rlm@0
|
155 [:death_place "varchar(255)"]
|
rlm@0
|
156 [:birth_date "date"]
|
rlm@0
|
157 [:death_date "date"])
|
rlm@0
|
158 (create-table
|
rlm@0
|
159 :essay_scientists
|
rlm@0
|
160 [:id "integer"]
|
rlm@0
|
161 [:name "varchar(255)"]
|
rlm@0
|
162 [:surname "varchar(255)"])))
|
rlm@0
|
163
|
rlm@0
|
164 (def fill-tables-command "mysql -u root -p clojure_rlm < scientists-a.in")
|
rlm@0
|
165
|
rlm@0
|
166
|
rlm@0
|
167
|
rlm@0
|
168 (defmethod < [java.sql.Date java.sql.Date] [a b]
|
rlm@0
|
169 ({-1 true 0 false 1 false}
|
rlm@0
|
170 (.compareTo a b)))
|
rlm@0
|
171
|
rlm@0
|
172 (defmethod > [java.sql.Date java.sql.Date]
|
rlm@0
|
173 ([a b]
|
rlm@0
|
174 ({-1 true 0 false 1 false}
|
rlm@0
|
175 (.compareTo a b))))
|
rlm@0
|
176
|
rlm@0
|
177
|
rlm@0
|
178 ;; they can have the same date of birth and death!!!
|
rlm@0
|
179 (defn contemps [birth death]
|
rlm@0
|
180 (with-connection *db*
|
rlm@0
|
181 @(select
|
rlm@0
|
182 (table :scientists)
|
rlm@0
|
183 (where
|
rlm@0
|
184 (or
|
rlm@0
|
185 (and (<= :birth_date birth) (< birth :death_date))
|
rlm@0
|
186 (and (< :birth_date death) (<= death :death_date))
|
rlm@0
|
187 (and (<= birth :birth_date) (< :birth_date death))
|
rlm@0
|
188 (and (< birth :death_date) (<= :death_date death)))))))
|
rlm@0
|
189
|
rlm@0
|
190 (defn essay-scientists []
|
rlm@0
|
191 @(table *db* :essay_scientists))
|
rlm@0
|
192
|
rlm@0
|
193 (defn get-info [table-name s]
|
rlm@0
|
194 @(select
|
rlm@0
|
195 (select (table *db* table-name)
|
rlm@0
|
196 (where (= :name (:name s))))
|
rlm@0
|
197 (where(= :surname (:surname s)))))
|
rlm@0
|
198
|
rlm@0
|
199 (defn century* [#^java.sql.Date d]
|
rlm@0
|
200 (* 100
|
rlm@0
|
201 (.getCenturyOfEra
|
rlm@0
|
202 (LocalDate. d))))
|
rlm@0
|
203
|
rlm@0
|
204
|
rlm@0
|
205 (defn century [#^java.sql.Date d]
|
rlm@0
|
206 (* 100 (clojure.core/unchecked-divide (+ 1900 (.getYear d)) 100)))
|
rlm@0
|
207
|
rlm@0
|
208
|
rlm@0
|
209
|
rlm@0
|
210 (defn get-scientist-data [s]
|
rlm@0
|
211 (let [data (first (get-info :scientists s))
|
rlm@0
|
212 locations (get-info :scientist_whereabouts s)
|
rlm@0
|
213 ideas (map :idea (get-info :ideas s))
|
rlm@0
|
214 birth (:birth_date data)
|
rlm@0
|
215 death (:death_date data)
|
rlm@0
|
216 name (:name data)
|
rlm@0
|
217 surname (:surname data)
|
rlm@0
|
218 contemps
|
rlm@0
|
219 (remove #(and (= (:name %) name) (= (:surname %) surname))
|
rlm@0
|
220 (map #(select-keys % [:name :surname])
|
rlm@0
|
221 (contemps birth death)))
|
rlm@0
|
222 century (century birth)]
|
rlm@0
|
223 {:data data :ideas ideas :locations locations :contemps contemps :century century}))
|
rlm@0
|
224
|
rlm@0
|
225 (defn essay-date* [#^java.sql.Date d]
|
rlm@0
|
226 (let [t (LocalDate. d)]
|
rlm@0
|
227 (format "%02d/%02d/%04d" (.getDayOfMonth t) (.getMonthOfYear t) (.getYear t))))
|
rlm@0
|
228
|
rlm@0
|
229 (defn essay-date [#^java.sql.Date d]
|
rlm@0
|
230 (format "%02d/%02d/%04d" (.getDate d) (inc (.getMonth d)) (+ 1900 (.getYear d))))
|
rlm@0
|
231
|
rlm@0
|
232 (defn fucked-sort [m]
|
rlm@0
|
233 (let [surname (:surname m)
|
rlm@0
|
234 name (:name m)
|
rlm@0
|
235 [surname n1] (.split surname " ")
|
rlm@0
|
236 [name n2] (.split name " ")
|
rlm@0
|
237 n1 (Integer/parseInt n1)
|
rlm@0
|
238 n2 (Integer/parseInt n2)]
|
rlm@0
|
239 [surname n1 name n2]))
|
rlm@0
|
240
|
rlm@0
|
241 (defn lexical-sort [m]
|
rlm@0
|
242 (let [surname (:surname m)
|
rlm@0
|
243 name (:name m)]
|
rlm@0
|
244 [surname name]))
|
rlm@0
|
245
|
rlm@0
|
246
|
rlm@0
|
247 (defn-memo essay [s]
|
rlm@0
|
248 (let [info (get-scientist-data s)
|
rlm@0
|
249 name (:name (:data info))
|
rlm@0
|
250 surname (:surname (:data info))]
|
rlm@0
|
251 (str name
|
rlm@0
|
252 " "
|
rlm@0
|
253 surname
|
rlm@0
|
254 " ["
|
rlm@0
|
255 (:birth_place (:data info))
|
rlm@0
|
256 " "
|
rlm@0
|
257 (essay-date (:birth_date (:data info)))
|
rlm@0
|
258 ", "
|
rlm@0
|
259 (:death_place (:data info))
|
rlm@0
|
260 " "
|
rlm@0
|
261 (essay-date (:death_date (:data info)))
|
rlm@0
|
262 "]"
|
rlm@0
|
263 " is one of the most famous scientists of "
|
rlm@0
|
264 (:century info)". "
|
rlm@0
|
265 "Between all " name "'s ideas we mention: "
|
rlm@0
|
266 (apply str (interpose ", " (sort (:ideas info))))
|
rlm@0
|
267 ". "
|
rlm@0
|
268 name " lived in: "
|
rlm@0
|
269 (apply
|
rlm@0
|
270 str
|
rlm@0
|
271 (interpose ", "
|
rlm@0
|
272 (map
|
rlm@0
|
273 (fn [entry]
|
rlm@0
|
274 (str (:country entry)
|
rlm@0
|
275 " from "
|
rlm@0
|
276 (essay-date (:immigration_date entry)) " to "
|
rlm@0
|
277 (essay-date (:emigration_date entry))))
|
rlm@0
|
278 (sort-by :immigration_date (:locations info)))))
|
rlm@0
|
279 ". "
|
rlm@0
|
280 name
|
rlm@0
|
281 " was a contemporary of "
|
rlm@0
|
282 (apply
|
rlm@0
|
283 str
|
rlm@0
|
284 (interpose
|
rlm@0
|
285 ", "
|
rlm@0
|
286 (map (fn [entry]
|
rlm@0
|
287 (str (:name entry)
|
rlm@0
|
288 " "
|
rlm@0
|
289 (:surname entry)))
|
rlm@0
|
290
|
rlm@0
|
291 (sort-by lexical-sort
|
rlm@0
|
292 (:contemps info)))))
|
rlm@0
|
293 ".\n\n" )))
|
rlm@0
|
294
|
rlm@0
|
295 (defn essays []
|
rlm@0
|
296 (map essay (essay-scientists)))
|
rlm@0
|
297
|
rlm@0
|
298
|
rlm@0
|
299 (defn main [[username password db-name]]
|
rlm@0
|
300 (let [db-host *host*
|
rlm@0
|
301 db-port *port*
|
rlm@0
|
302 db {:classname "com.mysql.jdbc.Driver"
|
rlm@0
|
303 :subprotocol "mysql"
|
rlm@0
|
304 :subname (str "//" db-host ":" db-port "/" db-name)
|
rlm@0
|
305 :user username
|
rlm@0
|
306 :password password}]
|
rlm@0
|
307 (binding [*db* db]
|
rlm@0
|
308 (print (apply str (essays))))))
|
rlm@0
|
309
|
rlm@0
|
310 (def desired-md5 "e436d54f87c86bffb5d1b38d5f3e136b")
|
rlm@0
|
311
|
rlm@0
|
312 (if (command-line?)
|
rlm@0
|
313 (main *command-line-args*))
|
rlm@0
|
314
|
rlm@0
|
315
|
rlm@0
|
316
|
rlm@0
|
317
|