Skip to content
Snippets Groups Projects
Commit fe389848 authored by Cam Saül's avatar Cam Saül
Browse files

Don't update MySQL since the new JDBC driver requires Java 8+ :cry:

parent bc61bf76
Branches
Tags
No related merge requests found
......@@ -16,7 +16,7 @@
[org.clojure/core.memoize "0.5.9"] ; needed by core.match; has useful FIFO, LRU, etc. caching mechanisms
[org.clojure/data.csv "0.1.3"] ; CSV parsing / generation
[org.clojure/java.classpath "0.2.3"]
[org.clojure/java.jdbc "0.5.8"] ; basic jdbc access from clojure
[org.clojure/java.jdbc "0.4.2"] ; basic jdbc access from clojure. *** DON'T UPDATE THIS UNTIL KORMA IS UPDATED TO STOP USING DEPRECATED FN SIGNATURES ***
[org.clojure/math.numeric-tower "0.0.4"] ; math functions like `ceil`
[org.clojure/tools.logging "0.3.1"] ; logging framework
[org.clojure/tools.namespace "0.2.10"]
......@@ -52,7 +52,7 @@
com.sun.jmx/jmxri]]
[medley "0.7.4"] ; lightweight lib of useful functions
[metabase/throttle "1.0.1"] ; Tools for throttling access to API endpoints and other code pathways
[mysql/mysql-connector-java "6.0.2"] ; MySQL JDBC driver
[mysql/mysql-connector-java "5.1.38"] ; MySQL JDBC driver *** DON'T UPDATE THIS YET - NEW VERSION IS JAVA 8+ ONLY: http://dev.mysql.com/doc/connector-j/6.0/en/connector-j-whats-new.html ***
[net.sf.cssbox/cssbox "4.11" ; HTML / CSS rendering
:exclusions [org.slf4j/slf4j-api]]
[net.sourceforge.jtds/jtds "1.3.1"] ; Open Source SQL Server driver
......@@ -93,7 +93,7 @@
#"^metabase\.sample-data$"
#"^metabase\.http-client$"]}
:profiles {:dev {:dependencies [[org.clojure/tools.nrepl "0.2.12"] ; REPL <3
[expectations "2.1.3"] ; unit tests
[expectations "2.1.3"] ; unit tests *** DON'T UPDATE THIS UNTIL WE REMOVE USES OF DEPRECATED EXPECT-LET IN THE CODEBASE ***
[ring/ring-mock "0.3.0"]]
:plugins [[docstring-checker "1.0.0"] ; Check that all public vars have docstrings. Run with 'lein docstring-checker'
[jonase/eastwood "0.2.3"
......
......@@ -237,7 +237,7 @@
(let [all-schemas (set (map :table_schem (jdbc/result-set-seq (.getSchemas metadata))))
schemas (set/difference all-schemas (excluded-schemas driver))]
(set (for [schema schemas
table-name (mapv :table_name (jdbc/result-set-seq (.getTables metadata nil schema nil (into-array String ["TABLE", "VIEW"]))))]
table-name (mapv :table_name (jdbc/result-set-seq (.getTables metadata nil schema "%" (into-array String ["TABLE", "VIEW"]))))] ; tablePattern "%" = match all tables
{:name table-name
:schema schema}))))
......@@ -246,7 +246,7 @@
Fetch *all* Tables, then filter out ones whose schema is in `excluded-schemas` Clojure-side."
[driver, ^DatabaseMetaData metadata]
(set (for [table (filter #(not (contains? (excluded-schemas driver) (:table_schem %)))
(jdbc/result-set-seq (.getTables metadata nil nil nil (into-array String ["TABLE", "VIEW"]))))]
(jdbc/result-set-seq (.getTables metadata nil nil "%" (into-array String ["TABLE", "VIEW"]))))] ; tablePattern "%" = match all tables
{:name (:table_name table)
:schema (:table_schem table)})))
......
......@@ -59,16 +59,25 @@
:VARCHAR :TextField
:YEAR :IntegerField} (keyword (s/replace (name column-type) #"\sUNSIGNED$" "")))) ; strip off " UNSIGNED" from end if present
(defn- connection-details->spec [_ details]
(def ^:private ^:const connection-args
"Map of args for the MySQL JDBC connection string.
Full list of is options is available here: http://dev.mysql.com/doc/connector-j/6.0/en/connector-j-reference-configuration-properties.html"
{:zeroDateTimeBehavior :convertToNull ; 0000-00-00 dates are valid in MySQL; convert these to `null` when they come back because they're illegal in Java
:useUnicode :true ; Force UTF-8 encoding of results
:characterEncoding :UTF8
:characterSetResults :UTF8})
(def ^:private ^:const connection-args-string
(apply str "?" (interpose \& (for [[k v] connection-args]
(str (name k) \= (name v))))))
(defn- connection-details->spec [details]
(-> details
(set/rename-keys {:dbname :db})
kdb/mysql
;; 0000-00-00 dates are valid in MySQL, but JDBC barfs when queries return them because java.sql.Date doesn't allow it.
;; Add a param to the end of the connection string that tells MySQL to convert 0000-00-00 dates to NULL when returning them.
;; Also add params to force UTF-8 encoding of results
(update :subname (u/rpartial str "?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF8&characterSetResults=UTF8"))))
(update :subname (u/rpartial str connection-args-string))))
(defn- unix-timestamp->timestamp [_ expr seconds-or-milliseconds]
(defn- unix-timestamp->timestamp [expr seconds-or-milliseconds]
(k/sqlfn :FROM_UNIXTIME (case seconds-or-milliseconds
:seconds expr
:milliseconds (kx// expr (k/raw 1000)))))
......@@ -81,7 +90,7 @@
(defn- trunc-with-format [format-str expr]
(str-to-date format-str (date-format format-str expr)))
(defn- date [_ unit expr]
(defn- date [unit expr]
(case unit
:default expr
:minute (trunc-with-format "%Y-%m-%d %H:%i" expr)
......@@ -115,10 +124,10 @@
:quarter-of-year (kx/quarter expr)
:year (kx/year expr)))
(defn- date-interval [_ unit amount]
(defn- date-interval [unit amount]
(kutils/generated (format "DATE_ADD(NOW(), INTERVAL %d %s)" (int amount) (s/upper-case (name unit)))))
(defn- humanize-connection-error-message [_ message]
(defn- humanize-connection-error-message [message]
(condp re-matches message
#"^Communications link failure\s+The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.$"
(driver/connection-error-messages :cannot-connect-check-host-and-port)
......@@ -143,7 +152,7 @@
(u/strict-extend MySQLDriver
driver/IDriver
(merge (sql/IDriverSQLDefaultsMixin)
{:date-interval date-interval
{:date-interval (u/drop-first-arg date-interval)
:details-fields (constantly [{:name "host"
:display-name "Host"
:default "localhost"}
......@@ -163,20 +172,21 @@
:display-name "Database password"
:type :password
:placeholder "*******"}])
:humanize-connection-error-message humanize-connection-error-message})
:humanize-connection-error-message (u/drop-first-arg humanize-connection-error-message)})
sql/ISQLDriver
(merge (sql/ISQLDriverDefaultsMixin)
{:active-tables sql/post-filtered-active-tables
:column->base-type (u/drop-first-arg column->base-type)
:connection-details->spec connection-details->spec
:date date
:connection-details->spec (u/drop-first-arg connection-details->spec)
:date (u/drop-first-arg date)
:excluded-schemas (constantly #{"INFORMATION_SCHEMA"})
:string-length-fn (constantly :CHAR_LENGTH)
;; If this fails you need to load the timezone definitions from your system into MySQL;
;; run the command `mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql`
;; See https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html for details
;; TODO - This can also be set via `sessionVariables` in the connection string, if that's more useful (?)
:set-timezone-sql (constantly "SET @@session.time_zone = ?;")
:unix-timestamp->timestamp unix-timestamp->timestamp}))
:unix-timestamp->timestamp (u/drop-first-arg unix-timestamp->timestamp)}))
(driver/register-driver! :mysql (MySQLDriver.))
......@@ -109,12 +109,9 @@
(defn- delete-old-revisions
"Delete old revisions of ENTITY with ID when there are more than `max-revisions` in the DB."
[entity id]
{:pre [(i/metabase-entity? entity)
(integer? id)]}
;; for some reason (offset max-revisions isn't working)
(let [old-revisions (drop max-revisions (db/sel :many :id Revision, :model (:name entity), :model_id id, (k/order :timestamp :DESC)))]
(when (seq old-revisions)
(k/delete Revision (k/where {:id [in old-revisions]})))))
{:pre [(i/metabase-entity? entity) (integer? id)]}
(when-let [old-revisions (seq (drop max-revisions (db/sel :many :id Revision, :model (:name entity), :model_id id, (k/order :timestamp :DESC))))]
(db/cascade-delete Revision :id [in old-revisions])))
(defn push-revision
"Record a new `Revision` for ENTITY with ID.
......@@ -158,7 +155,7 @@
;; Do the reversion of the object
(revert-to-revision entity id user-id serialized-instance)
;; Push a new revision to record this change
(let [last-revision (db/sel :one Revision :model (:name entity), :model_id id (k/order :id :DESC))
(let [last-revision (db/sel :one Revision, :model (:name entity), :model_id id, (k/order :id :DESC))
new-revision (db/ins Revision
:model (:name entity)
:model_id id
......
......@@ -20,7 +20,7 @@
:TextField "TEXT"
:TimeField "TIME"})
(defn- database->connection-details [_ context {:keys [database-name short-lived?]}]
(defn- database->connection-details [context {:keys [database-name short-lived?]}]
(merge {:host "localhost"
:port 3306
:timezone :America/Los_Angeles
......@@ -30,19 +30,18 @@
(when (= context :db)
{:db database-name})))
(defn- quote-name [_ nm]
(defn- quote-name [nm]
(str \` nm \`))
(u/strict-extend MySQLDriver
generic/IGenericSQLDatasetLoader
(merge generic/DefaultsMixin
{:execute-sql! generic/sequentially-execute-sql!
:field-base-type->sql-type (fn [_ base-type]
(field-base-type->sql-type base-type))
{:execute-sql! generic/sequentially-execute-sql! ; TODO - we might be able to do SQL all at once by setting `allowMultiQueries=true` on the connection string
:field-base-type->sql-type (u/drop-first-arg field-base-type->sql-type)
:load-data! generic/load-data-all-at-once!
:pk-sql-type (constantly "INTEGER NOT NULL AUTO_INCREMENT")
:quote-name quote-name})
:quote-name (u/drop-first-arg quote-name)})
i/IDatasetLoader
(merge generic/IDatasetLoaderMixin
{:database->connection-details database->connection-details
{:database->connection-details (u/drop-first-arg database->connection-details)
:engine (constantly :mysql)}))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment