diff src/scientist_sql.clj @ 0:307a81e46071 tip

initial committ
author Robert McIntyre <rlm@mit.edu>
date Tue, 18 Oct 2011 01:17:49 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/scientist_sql.clj	Tue Oct 18 01:17:49 2011 -0700
     1.3 @@ -0,0 +1,317 @@
     1.4 +(ns coderloop.scientist-sql
     1.5 +  (:refer-clojure :only [])
     1.6 +  (:require rlm.ns-rlm rlm.light-base))
     1.7 +(rlm.ns-rlm/ns-clone rlm.light-base)
     1.8 +
     1.9 +
    1.10 +(use 'clojure.contrib.sql)               ;;' satisfy prettify
    1.11 +(import 'org.gjt.mm.mysql.Driver)
    1.12 +(use 'clojure.contrib.sql)
    1.13 +(import '[org.joda.time LocalDate ])
    1.14 +(undef distinct case compile drop take sort)
    1.15 +(use 'clojureql.core)
    1.16 +(import 'org.joda.time.DateMidnight)
    1.17 +(import 'java.io.File)
    1.18 +(use '[clojure.java.io :only [copy]])
    1.19 +(use '[clojure.contrib.shell-out :only [sh]])
    1.20 +(use '[clojure.string :only [split]])
    1.21 +(use '[coderloop [utils :only [md5]]])
    1.22 +
    1.23 +(defn sql-date [date]
    1.24 +  "Convert any Joda-readable date object (including a string) to a java.sql.Date"
    1.25 +    (java.sql.Date. (.. (LocalDate. date) toDateMidnight toInstant getMillis)))
    1.26 +
    1.27 +(def *port* 3306)
    1.28 +
    1.29 +(def *host* "localhost")
    1.30 +
    1.31 +(def *db-host* "localhost")
    1.32 +
    1.33 +(def *db-name* "clojure_rlm")
    1.34 +
    1.35 +(def *db* {:classname "com.mysql.jdbc.Driver"
    1.36 +	   :subprotocol "mysql"
    1.37 +	   :subname (str "//" *db-host* ":" *port* "/" *db-name*)
    1.38 +	   :user "root"
    1.39 +	   :password "sql1005025"})
    1.40 +
    1.41 +(def *db2* {:classname "com.mysql.jdbc.Driver"
    1.42 +	    :subprotocol "mysql"
    1.43 +	    :subname (str "//" *db-host* ":" *port* "/" "test_rlm")
    1.44 +	    :user "root"
    1.45 +	    :password "sql1005025"})
    1.46 +
    1.47 +
    1.48 +(def databases [:essay_scientists :scientists :ideas :scientist_whereabouts])
    1.49 +
    1.50 +(defmacro no-exceptions
    1.51 +  "Sweet relief like I never knew."
    1.52 +  [& forms]
    1.53 +  `(try ~@forms (catch Exception e# (.printStackTrace e#))))
    1.54 +
    1.55 +
    1.56 +(defn make-essay-scientists []
    1.57 +  (with-connection
    1.58 +    *db2*
    1.59 +    (no-exceptions (drop-table :essay_scientists))
    1.60 +    (create-table
    1.61 +     :essay_scientists
    1.62 +     [:id "integer"]
    1.63 +     [:name "varchar(255)"]
    1.64 +     [:surname "varchar(255)"])
    1.65 +    (insert-rows :essay_scientists
    1.66 +		 [1 "Isaac" "Newton"]
    1.67 +		 [2 "Albert" "Einstein"])))
    1.68 +
    1.69 +(defn make-scientists []
    1.70 +  (with-connection
    1.71 +    *db2*
    1.72 +    (no-exceptions (drop-table :scientists))
    1.73 +    (create-table
    1.74 +     :scientists
    1.75 +     [:name "varchar(255)"]
    1.76 +     [:surname "varchar(255)"]
    1.77 +     [:birth_place "varchar(255)"]
    1.78 +     [:death_place "varchar(255)"]
    1.79 +     [:birth_date "date"]
    1.80 +     [:death_date "date"])
    1.81 +    (insert-rows
    1.82 +     :scientists
    1.83 +     ["Albert" "Einstein" "Ulm" "Princeton" "1879-3-14" "1955-4-18"]
    1.84 +     ["Galileo" "Galilei" "Pisa" "Arcetri" "1564-2-15" "1645-1-8"]
    1.85 +     ["Enrico" "Fermi" "Roma" "Chicago" "1901-9-29" "1954-9-28"]
    1.86 +     ["Isaac" "Newton" "Woolsthorpe-by-Colsterworth" "London" "1643-1-4" "1727-3-31"]
    1.87 +     ["Marx" "Planck" "Kiel" "Göttingen" "1858-4-23" "1947-10-4"])))
    1.88 +
    1.89 +
    1.90 +(defn make-scientist-whereabouts []
    1.91 +  (with-connection *db2*
    1.92 +    (no-exceptions (drop-table :scientist_whereabouts ))
    1.93 +    (create-table
    1.94 +     :scientist_whereabouts
    1.95 +     [:name "varchar(255)"]
    1.96 +     [:surname "varchar(255)"]
    1.97 +     [:country "varchar(255)"]
    1.98 +     [:immigration_date "date"]
    1.99 +     [:emigration_date "date"])
   1.100 +    (insert-rows
   1.101 +     :scientist_whereabouts
   1.102 +     ["Galileo" "Galilei" "France" "1602-2-18" "1604-4-20"]
   1.103 +     ["Albert" "Einstein" "Uk" "1901-10-22" "1905-5-4"]
   1.104 +     ["Marx" "Planck" "Denmark" "1901-1-31" "1945-7-4"]
   1.105 +     ["Albert" "Einstein" "France" "1908-11-7" "1930-3-12"]
   1.106 +     ["Enrico" "Fermi" "Us" "1924-12-19" "1954-9-28"]
   1.107 +     ["Isaac" "Newton" "Uk" "1688-9-8" "1690-7-12"]
   1.108 +     ["Albert" "Einstein" "US" "1935-10-22" "1955-4-18"]
   1.109 +     ["Isaac" "Newton" "Germany" "1690-9-28" "1705-4-6"])))
   1.110 +
   1.111 +
   1.112 +(defn make-ideas []
   1.113 +  (with-connection *db2*
   1.114 +    (no-exceptions (drop-table :ideas))
   1.115 +    (create-table
   1.116 +     :ideas
   1.117 +     [:name     "varchar(255)"]
   1.118 +     [:surname  "varchar(255)"]
   1.119 +     [:idea     "varchar(255)"])
   1.120 +    (insert-rows
   1.121 +     :ideas
   1.122 +     ["Albert" "Einstein" "Theory of relativity (general)"]
   1.123 +     ["Enrico" "Fermi" "First nuclear reactor"]
   1.124 +     ["Albert" "Einstein" "Photoelectric effect"]
   1.125 +     ["Isaac" "Newton" "Gravity"]
   1.126 +     ["Galileo" "Galilei" "Telescope"]
   1.127 +     ["Albert" "Einstein" "Theory of relativity (special)"]
   1.128 +     ["Isaac" "Newton" "Dark matter"])))
   1.129 +
   1.130 +(defn clear-tables []
   1.131 +  (with-connection *db2* (dorun (map drop-table databases))))
   1.132 +
   1.133 +(defn fill-tables []
   1.134 +  (make-ideas)
   1.135 +  (make-essay-scientists)
   1.136 +  (make-scientist-whereabouts)
   1.137 +  (make-scientists))
   1.138 +
   1.139 +(defn make-empty-tables []
   1.140 +  (with-connection *db2*
   1.141 +    (create-table
   1.142 +     :ideas
   1.143 +     [:name     "varchar(255)"]
   1.144 +     [:surname  "varchar(255)"]
   1.145 +     [:idea     "varchar(255)"])
   1.146 +    (create-table
   1.147 +     :scientist_whereabouts
   1.148 +     [:name "varchar(255)"]
   1.149 +     [:surname "varchar(255)"]
   1.150 +     [:country "varchar(255)"]
   1.151 +     [:immigration_date "date"]
   1.152 +     [:emigration_date "date"])
   1.153 +    (create-table
   1.154 +     :scientists
   1.155 +     [:name "varchar(255)"]
   1.156 +     [:surname "varchar(255)"]
   1.157 +     [:birth_place "varchar(255)"]
   1.158 +     [:death_place "varchar(255)"]
   1.159 +     [:birth_date "date"]
   1.160 +     [:death_date "date"])
   1.161 +    (create-table
   1.162 +     :essay_scientists
   1.163 +     [:id "integer"]
   1.164 +     [:name "varchar(255)"]
   1.165 +     [:surname "varchar(255)"])))
   1.166 +
   1.167 +(def fill-tables-command  "mysql -u root -p clojure_rlm < scientists-a.in")
   1.168 +
   1.169 +    
   1.170 +
   1.171 +(defmethod < [java.sql.Date  java.sql.Date] [a b]
   1.172 +	   ({-1 true 0 false 1 false}
   1.173 +	   (.compareTo a b)))
   1.174 +
   1.175 +(defmethod > [java.sql.Date  java.sql.Date]
   1.176 +  ([a b]
   1.177 +     ({-1 true 0 false 1 false}
   1.178 +      (.compareTo a b))))
   1.179 +
   1.180 +
   1.181 +;; they can have the same date of birth and death!!!
   1.182 +(defn contemps [birth death]
   1.183 +  (with-connection *db*
   1.184 +    @(select
   1.185 +      (table :scientists)
   1.186 +      (where
   1.187 +       (or
   1.188 +	(and (<= :birth_date birth) (< birth :death_date))
   1.189 +	(and  (< :birth_date death) (<= death :death_date))
   1.190 +	(and  (<=  birth :birth_date) (< :birth_date death))
   1.191 +	(and  (<  birth :death_date) (<= :death_date death)))))))
   1.192 +
   1.193 +(defn essay-scientists []
   1.194 +  @(table *db* :essay_scientists))
   1.195 +
   1.196 +(defn get-info [table-name s]
   1.197 +  @(select 
   1.198 +    (select (table *db* table-name)
   1.199 +	    (where (= :name (:name s))))
   1.200 +    (where(= :surname (:surname s)))))
   1.201 +
   1.202 +(defn century* [#^java.sql.Date d]
   1.203 +  (* 100
   1.204 +     (.getCenturyOfEra
   1.205 +      (LocalDate. d))))
   1.206 +
   1.207 +
   1.208 +(defn century [#^java.sql.Date d]
   1.209 +  (* 100 (clojure.core/unchecked-divide (+ 1900 (.getYear d)) 100)))
   1.210 +
   1.211 +
   1.212 +
   1.213 +(defn get-scientist-data [s]
   1.214 +  (let [data (first (get-info :scientists s))
   1.215 +	locations (get-info :scientist_whereabouts s)
   1.216 +	ideas (map :idea (get-info :ideas s))
   1.217 +	birth (:birth_date data)
   1.218 +	death (:death_date data)
   1.219 +	name (:name data)
   1.220 +	surname (:surname data)
   1.221 +	contemps
   1.222 +	(remove #(and (= (:name %) name) (= (:surname %) surname))
   1.223 +		(map #(select-keys % [:name :surname])
   1.224 +		     (contemps birth death)))
   1.225 +	century (century birth)]
   1.226 +    {:data data :ideas ideas :locations locations :contemps contemps :century century}))
   1.227 +
   1.228 +(defn essay-date* [#^java.sql.Date d]
   1.229 +  (let [t (LocalDate. d)]
   1.230 +    (format "%02d/%02d/%04d" (.getDayOfMonth t) (.getMonthOfYear t) (.getYear t))))
   1.231 +
   1.232 +(defn essay-date [#^java.sql.Date d]
   1.233 +  (format "%02d/%02d/%04d" (.getDate d) (inc (.getMonth d)) (+ 1900 (.getYear d))))
   1.234 +  
   1.235 +(defn fucked-sort [m]
   1.236 +  (let [surname (:surname m)
   1.237 +	name (:name m)
   1.238 +	[surname n1] (.split surname " ")
   1.239 +	[name n2] (.split name " ")
   1.240 +	n1 (Integer/parseInt n1)
   1.241 +	n2 (Integer/parseInt n2)]
   1.242 +    [surname n1 name n2]))
   1.243 +
   1.244 +(defn lexical-sort [m]
   1.245 +  (let [surname (:surname m)
   1.246 +	name (:name m)]
   1.247 +    [surname name]))
   1.248 +  
   1.249 +
   1.250 +(defn-memo essay [s]
   1.251 +  (let [info (get-scientist-data s)
   1.252 +	name (:name (:data info))
   1.253 +	surname (:surname (:data info))]
   1.254 +       (str name
   1.255 +	    " "
   1.256 +	    surname
   1.257 +	    " ["
   1.258 +	    (:birth_place (:data info))
   1.259 +	    " "
   1.260 +	    (essay-date (:birth_date (:data info)))
   1.261 +	    ", "
   1.262 +	    (:death_place (:data info))
   1.263 +	    " "
   1.264 +	    (essay-date (:death_date (:data info)))
   1.265 +	    "]"
   1.266 +	    " is one of the most famous scientists of "
   1.267 +	    (:century info)". "
   1.268 +	    "Between all " name "'s ideas we mention: "
   1.269 +	    (apply str (interpose ", " (sort (:ideas info))))
   1.270 +	    ". "
   1.271 +	    name " lived in: "
   1.272 +	    (apply
   1.273 +	     str
   1.274 +	     (interpose ", "
   1.275 +			(map
   1.276 +			 (fn [entry]
   1.277 +			   (str (:country entry)
   1.278 +				" from "
   1.279 +				(essay-date (:immigration_date entry)) " to "
   1.280 +				(essay-date (:emigration_date entry))))
   1.281 +			 (sort-by :immigration_date  (:locations info)))))
   1.282 +	    ". "
   1.283 +	    name
   1.284 +	    " was a contemporary of "
   1.285 +	    (apply
   1.286 +	     str
   1.287 +	     (interpose
   1.288 +	      ", "
   1.289 +	      (map (fn [entry]
   1.290 +		     (str (:name entry)
   1.291 +			  " "
   1.292 +			  (:surname entry)))
   1.293 +		   
   1.294 +		   (sort-by lexical-sort
   1.295 +			    (:contemps info)))))
   1.296 +	     ".\n\n" )))
   1.297 +
   1.298 +(defn essays []
   1.299 +  (map essay (essay-scientists)))
   1.300 +
   1.301 +
   1.302 +(defn main [[username password db-name]]
   1.303 +  (let [db-host *host*
   1.304 +	db-port *port*
   1.305 +	db {:classname "com.mysql.jdbc.Driver"
   1.306 +	    :subprotocol "mysql"
   1.307 +	    :subname (str "//" db-host ":" db-port "/" db-name)
   1.308 +	    :user username
   1.309 +	    :password password}]
   1.310 +    (binding [*db* db]
   1.311 +      (print (apply str (essays))))))
   1.312 +
   1.313 +(def desired-md5 "e436d54f87c86bffb5d1b38d5f3e136b")
   1.314 +
   1.315 +(if (command-line?)
   1.316 +  (main *command-line-args*))
   1.317 +    
   1.318 +    
   1.319 +	    
   1.320 +