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

Merge pull request #562 from metabase/clojure_1.7

Bump Clojure to 1.7. Bump a few other deps
parents 0479a4da e14a67e1
No related branches found
No related tags found
No related merge requests found
Showing
with 81 additions and 78 deletions
......@@ -6,8 +6,7 @@
:url "http://metabase.com/"
:min-lein-version "2.5.0"
:aliases {"test" ["with-profile" "+expectations" "expectations"]}
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/core.async "LATEST"] ; facilities for async programming + communication (using 'LATEST' because this is an alpha library)
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/core.match "0.3.0-alpha4"] ; optimized pattern matching library for Clojure
[org.clojure/math.numeric-tower "0.0.4"] ; math functions like `ceil`
[org.clojure/core.memoize "0.5.7"] ; needed by core.match; has useful FIFO, LRU, etc. caching mechanisms
......@@ -19,16 +18,15 @@
[org.clojure/tools.macro "0.1.5"] ; tools for writing macros
[org.clojure/tools.namespace "0.2.10"]
[org.clojure/tools.reader "0.9.2"] ; Need to explictly specify this dep otherwise expectations doesn't seem to work right :'(
[org.clojure/tools.trace "0.7.8"] ; "tracing macros/fns to help you see what your code is doing"
[amalloy/ring-gzip-middleware "0.1.3"] ; Ring middleware to GZIP responses if client can handle it
[cheshire "5.5.0"] ; fast JSON encoding (used by Ring JSON middleware)
[clj-http-lite "0.2.1"] ; HTTP client; lightweight version of clj-http that uses HttpURLConnection instead of Apache
[clj-time "0.9.0"] ; library for dealing with date/time
[clj-time "0.10.0"] ; library for dealing with date/time
[colorize "0.1.1" :exclusions [org.clojure/clojure]] ; string output with ANSI color codes (for logging)
[com.cemerick/friend "0.2.1"] ; auth library
[com.draines/postal "1.11.3"] ; SMTP library
[com.h2database/h2 "1.4.187"] ; embedded SQL database
[com.mattbertolini/liquibase-slf4j "1.2.1"]
[com.mattbertolini/liquibase-slf4j "1.2.1"] ; Java Migrations lib
[com.novemberain/monger "2.1.0"] ; MongoDB Driver
[compojure "1.3.4"] ; HTTP Routing library built on Ring
[environ "1.0.0"] ; easy environment management
......@@ -40,11 +38,11 @@
com.sun.jdmk/jmxtools
com.sun.jmx/jmxri]]
[medley "0.6.0"] ; lightweight lib of useful functions
[org.liquibase/liquibase-core "3.3.5"] ; migration management (Java lib)
[org.liquibase/liquibase-core "3.4.0"] ; migration management (Java lib)
[org.slf4j/slf4j-log4j12 "1.7.12"]
[org.yaml/snakeyaml "1.15"] ; YAML parser (required by liquibase)
[postgresql "9.3-1102.jdbc41"] ; Postgres driver
[ring/ring-jetty-adapter "1.3.2"] ; Ring adapter using Jetty webserver (used to run a Ring server for unit tests)
[ring/ring-jetty-adapter "1.4.0"] ; Ring adapter using Jetty webserver (used to run a Ring server for unit tests)
[ring/ring-json "0.3.1"] ; Ring middleware for reading/writing JSON automatically
[swiss-arrows "1.0.0"]] ; 'Magic wand' macro -<>, etc.
:plugins [[lein-environ "1.0.0"] ; easy access to environment variables
......@@ -62,18 +60,18 @@
:exclude-linters [:constant-test ; korma macros generate some forms with if statements that are always logically true or false
:suspicious-expression]} ; core.match macros generate some forms like (and expr) which is "suspicious"
:profiles {:dev {:dependencies [[org.clojure/tools.nrepl "0.2.10"] ; REPL <3
[expectations "2.1.1"] ; unit tests
[expectations "2.1.2"] ; unit tests
[marginalia "0.8.0"] ; for documentation
[ring/ring-mock "0.2.0"]]
:plugins [[cider/cider-nrepl "0.9.0"] ; Interactive development w/ cider NREPL in Emacs
:plugins [[cider/cider-nrepl "0.9.1"] ; Interactive development w/ cider NREPL in Emacs
[jonase/eastwood "0.2.1"] ; Linting
[lein-ancient "0.6.5"] ; Check project for outdated dependencies + plugins w/ 'lein ancient'
[lein-ancient "0.6.7"] ; Check project for outdated dependencies + plugins w/ 'lein ancient'
[lein-bikeshed "0.2.0"] ; Linting
[lein-environ "1.0.0"] ; Specify env-vars in project.clj
[lein-expectations "0.0.8"] ; run unit tests with 'lein expectations'
[lein-instant-cheatsheet "2.1.1"] ; use awesome instant cheatsheet created by yours truly w/ 'lein instant-cheatsheet'
[lein-instant-cheatsheet "2.1.4"] ; use awesome instant cheatsheet created by yours truly w/ 'lein instant-cheatsheet'
[lein-marginalia "0.8.0"] ; generate documentation with 'lein marg'
[refactor-nrepl "1.1.0-SNAPSHOT"]] ; support for advanced refactoring in Emacs/LightTable
[refactor-nrepl "1.1.0"]] ; support for advanced refactoring in Emacs/LightTable
:global-vars {*warn-on-reflection* true} ; Emit warnings on all reflection calls
:jvm-opts ["-Dlogfile.path=target/log"
"-Xms1024m" ; give JVM a decent heap size to start with
......
(ns metabase.api.card
(:require [compojure.core :refer [GET POST DELETE PUT]]
[korma.core :refer :all]
[korma.core :as k]
[medley.core :refer [mapply]]
[metabase.api.common :refer :all]
[metabase.db :refer :all]
......@@ -29,9 +29,9 @@
[f]
{f CardFilterOption}
(-> (case (or f :all) ; default value for `f` is `:all`
:all (sel :many Card (order :name :ASC) (where (or {:creator_id *current-user-id*}
{:public_perms [> common/perms-none]})))
:mine (sel :many Card :creator_id *current-user-id* (order :name :ASC))
:all (sel :many Card (k/order :name :ASC) (k/where (or {:creator_id *current-user-id*}
{:public_perms [> common/perms-none]})))
:mine (sel :many Card :creator_id *current-user-id* (k/order :name :ASC))
:fav (->> (-> (sel :many [CardFavorite :card_id] :owner_id *current-user-id*)
(hydrate :card))
(map :card)
......
......@@ -3,8 +3,8 @@
(:require [clojure.tools.logging :as log]
[cheshire.core :as json]
[compojure.core :refer [defroutes]]
[korma.core :refer :all :exclude [update]]
[medley.core :refer :all]
[korma.core :as k]
[medley.core :as m]
[metabase.api.common.internal :refer :all]
[metabase.db :refer :all]
[metabase.db.internal :refer [entity->korma]]
......@@ -327,7 +327,7 @@
(defannotation Boolean
"Param must be a boolean (this does *not* cast the param)."
[symb value :nillable]
(checkp-with boolean? symb value "value must be a boolean."))
(checkp-with m/boolean? symb value "value must be a boolean."))
(defannotation Dict
"Param must be a dictionary (this does *not* cast the param)."
......@@ -406,7 +406,7 @@
`defendpoint` in the current namespace."
[& additional-routes]
(let [api-routes (->> (ns-publics *ns*)
(filter-vals #(:is-endpoint? (meta %)))
(m/filter-vals #(:is-endpoint? (meta %)))
(map first))]
`(defroutes ~'routes ~@api-routes ~@additional-routes)))
......
(ns metabase.api.dash
"/api/dash endpoints."
(:require [compojure.core :refer [GET POST PUT DELETE]]
[korma.core :refer :all]
[korma.core :as k]
[metabase.api.common :refer :all]
[metabase.db :refer :all]
(metabase.models [hydrate :refer [hydrate]]
......@@ -18,8 +18,8 @@
[f]
{f FilterOptionAllOrMine}
(-> (case (or f :all)
:all (sel :many Dashboard (where (or {:creator_id *current-user-id*}
{:public_perms [> common/perms-none]})))
:all (sel :many Dashboard (k/where (or {:creator_id *current-user-id*}
{:public_perms [> common/perms-none]})))
:mine (sel :many Dashboard :creator_id *current-user-id*))
(hydrate :creator)))
......
(ns metabase.api.meta.db
"/api/meta/db endpoints."
(:require [compojure.core :refer [GET POST PUT DELETE]]
[korma.core :refer :all]
[korma.core :as k]
[metabase.api.common :refer :all]
[metabase.db :refer :all]
[metabase.driver :as driver]
......@@ -20,7 +20,7 @@
(defendpoint GET "/"
"Fetch all `Databases`."
[]
(sel :many Database (order :name)))
(sel :many Database (k/order :name)))
(defendpoint POST "/"
"Add a new `Database`."
......@@ -112,7 +112,7 @@
"Get a list of all `Tables` in `Database`."
[id]
(read-check Database id)
(-> (sel :many Table :db_id id :active true (order :name))
(-> (sel :many Table :db_id id :active true (k/order :name))
(hydrate :human_readable_name)))
(defendpoint GET "/:id/idfields"
......
(ns metabase.api.meta.table
"/api/meta/table endpoints."
(:require [compojure.core :refer [GET POST PUT]]
[korma.core :refer :all]
[korma.core :as k]
[metabase.api.common :refer :all]
[metabase.db :refer :all]
(metabase.models [hydrate :refer :all]
......@@ -19,7 +19,7 @@
(defendpoint GET "/"
"Get all `Tables`."
[]
(-> (sel :many Table :active true (order :name :ASC))
(-> (sel :many Table :active true (k/order :name :ASC))
(hydrate :db :human_readable_name)
;; if for some reason a Table doesn't have rows set then set it to 0 so UI doesn't barf
(#(map (fn [table]
......@@ -49,7 +49,7 @@
"Get all `Fields` for `Table` with ID."
[id]
(read-check Table id)
(-> (sel :many Field :table_id id, :active true, :field_type [not= "sensitive"], (order :name :ASC))
(-> (sel :many Field :table_id id, :active true, :field_type [not= "sensitive"], (k/order :name :ASC))
(hydrate :human_readable_name)))
(defendpoint GET "/:id/query_metadata"
......
......@@ -3,7 +3,7 @@
(:require [clojure.tools.logging :as log]
[compojure.core :refer [defroutes GET POST DELETE]]
[hiccup.core :refer [html]]
[korma.core :as korma]
[korma.core :as k]
[metabase.api.common :refer :all]
[metabase.db :refer :all]
[metabase.email.messages :as email]
......@@ -18,7 +18,7 @@
[:as {{:keys [email password] :as body} :body}]
{email [Required Email]
password [Required NonEmptyString]}
(let [user (sel :one :fields [User :id :password_salt :password] :email email (korma/where {:is_active true}))]
(let [user (sel :one :fields [User :id :password_salt :password] :email email (k/where {:is_active true}))]
(checkp (not (nil? user))
; Don't leak whether the account doesn't exist or the password was incorrect
(symbol "password") "did not match stored password")
......
(ns metabase.driver
(:require clojure.java.classpath
[clojure.tools.logging :as log]
[medley.core :refer :all]
[medley.core :as m]
[metabase.db :refer [exists? ins sel upd]]
(metabase.driver [interface :as i]
[query-processor :as qp])
......@@ -227,7 +227,7 @@
(if id
;; execution has already been saved, so update it
(do
(mapply upd QueryExecution id query-execution)
(m/mapply upd QueryExecution id query-execution)
query-execution)
;; first time saving execution, so insert it
(mapply ins QueryExecution query-execution)))
(m/mapply ins QueryExecution query-execution)))
(ns metabase.driver.generic-sql
(:require [clojure.java.jdbc :as jdbc]
[clojure.tools.logging :as log]
[korma.core :refer :all]
[korma.core :as k]
[metabase.driver :as driver]
(metabase.driver [interface :refer :all]
[sync :as driver-sync])
......@@ -14,7 +14,7 @@
:standard-deviation-aggregations
:unix-timestamp-special-type-fields})
(defrecord SqlDriver [;; A set of additional features supported by a specific driver implmentation, e.g. :set-timezone for :postgres
(defrecord SqlDriver [ ;; A set of additional features supported by a specific driver implmentation, e.g. :set-timezone for :postgres
additional-supported-features
column->base-type
connection-details->connection-spec
......@@ -39,7 +39,7 @@
(can-connect-with-details? [_ details]
(let [connection (connection-details->connection-spec details)]
(= 1 (-> (exec-raw connection "SELECT 1" :results)
(= 1 (-> (k/exec-raw connection "SELECT 1" :results)
first
vals
first))))
......@@ -47,7 +47,7 @@
;; Query Processing
(wrap-process-query-middleware [_ qp]
(fn [query]
(qp query))) ; Nothing to do here
(qp query))) ; Nothing to do here
(process-query [_ query]
(qp/process-and-run query))
......@@ -95,9 +95,9 @@
ISyncDriverFieldAvgLength
(field-avg-length [_ field]
(or (some-> (korma-entity @(:table field))
(select (aggregate (avg (sqlfn* sql-string-length-fn
(raw (format "CAST(\"%s\" AS TEXT)" (name (:name field))))))
:len))
(k/select (k/aggregate (avg (k/sqlfn* sql-string-length-fn
(k/raw (format "CAST(\"%s\" AS TEXT)" (name (:name field))))))
:len))
first
:len
int)
......@@ -106,12 +106,12 @@
ISyncDriverFieldPercentUrls
(field-percent-urls [_ field]
(let [korma-table (korma-entity @(:table field))
total-non-null-count (-> (select korma-table
(aggregate (count :*) :count)
(where {(keyword (:name field)) [not= nil]})) first :count)]
total-non-null-count (-> (k/select korma-table
(k/aggregate (count :*) :count)
(k/where {(keyword (:name field)) [not= nil]})) first :count)]
(if (= total-non-null-count 0) 0.0
(let [url-count (or (-> (select korma-table
(aggregate (count :*) :count)
(where {(keyword (:name field)) [like "http%://_%.__%"]})) first :count)
(let [url-count (or (-> (k/select korma-table
(k/aggregate (count :*) :count)
(k/where {(keyword (:name field)) [like "http%://_%.__%"]})) first :count)
0)]
(float (/ url-count total-non-null-count)))))))
......@@ -4,7 +4,7 @@
[clojure.tools.logging :as log]
[clojure.string :as s]
[clojure.walk :as walk]
[korma.core :refer :all]
[korma.core :refer :all, :exclude [update]]
[metabase.config :as config]
[metabase.driver.query-processor :as qp]
(metabase.driver.generic-sql [native :as native]
......
......@@ -69,7 +69,7 @@
(qp (if (or (not (= ag-type :rows)) breakout fields) query
(-> query
(assoc-in [:query :fields-is-implicit] true)
(assoc-in [:query :fields] (->> (sel :many :fields [Field :name :base_type :special_type :table_id], :table_id source-table-id, :active true,
(assoc-in [:query :fields] (->> (sel :many :fields [Field :name :base_type :special_type :table_id :id], :table_id source-table-id, :active true,
:preview_display true, :field_type [not= "sensitive"], :parent_id nil, (k/order :position :asc), (k/order :id :desc))
(map expand/rename-mb-field-keys)
(map expand/map->Field)
......@@ -175,12 +175,13 @@
(defn- limit
"Add an implicit `limit` clause to queries with `rows` aggregations, and limit the maximum number of rows that can be returned in post-processing."
[qp]
(fn [{{{ag-type :aggregation-type} :aggregation, limit :limit} :query, :as query}]
(fn [{{{ag-type :aggregation-type} :aggregation, :keys [limit page]} :query, :as query}]
(let [query (cond-> query
(and (not limit)
(not page)
(= ag-type :rows)) (assoc-in [:query :limit] max-result-bare-rows))
results (qp query)]
(update-in results [:rows] (partial take max-result-rows)))))
(update results :rows (partial take max-result-rows)))))
(defn- pre-log-query [qp]
......@@ -188,7 +189,9 @@
(when-not *disable-qp-logging*
(log/debug (u/format-color 'magenta "\n\nPREPROCESSED/EXPANDED:\n%s"
;; obscure DB details when logging
(u/pprint-to-str (assoc-in query [:database :details] "**********")))))
(u/pprint-to-str (-> query
(assoc-in [:database :details] "**********")
(update :driver class))))))
(qp query)))
......
......@@ -110,15 +110,17 @@
(not (every? nil? clause))))))
(defn- parse [query-dict]
(update-in query-dict [:query] #(-<> (assoc %
:aggregation (parse-aggregation (:aggregation %))
:breakout (parse-breakout (:breakout %))
:fields (parse-fields (:fields %))
:filter (parse-filter (:filter %))
:order_by (parse-order-by (:order_by %)))
(set/rename-keys <> {:order_by :order-by
:source_table :source-table})
(m/filter-vals non-empty-clause? <>))))
;; TODO - we should parse the Page clause so we can validate it
;; And convert to a limit / offset clauses
(update query-dict :query #(-<> (assoc %
:aggregation (parse-aggregation (:aggregation %))
:breakout (parse-breakout (:breakout %))
:fields (parse-fields (:fields %))
:filter (parse-filter (:filter %))
:order_by (parse-order-by (:order_by %)))
(set/rename-keys <> {:order_by :order-by
:source_table :source-table})
(m/filter-vals non-empty-clause? <>))))
(defn rename-mb-field-keys
"Rename the keys in a Metabase `Field` to match the format of those in Query Expander `Fields`."
......@@ -350,15 +352,15 @@
^Field field])
(defparser parse-aggregation
["rows"] (->Aggregation :rows nil)
["count"] (->Aggregation :count nil)
["avg" field-id] (->Aggregation :avg (ph field-id))
["count" field-id] (->Aggregation :count (ph field-id))
["distinct" field-id] (->Aggregation :distinct (ph field-id))
["stddev" field-id] (do (assert-driver-supports :standard-deviation-aggregations)
(->Aggregation :stddev (ph field-id)))
["sum" field-id] (->Aggregation :sum (ph field-id))
["cum_sum" field-id] (->Aggregation :cumulative-sum (ph field-id)))
["rows"] (->Aggregation :rows nil)
["count"] (->Aggregation :count nil)
["avg" (field-id :guard Field?)] (->Aggregation :avg (ph field-id))
["count" (field-id :guard Field?)] (->Aggregation :count (ph field-id))
["distinct" (field-id :guard Field?)] (->Aggregation :distinct (ph field-id))
["stddev" (field-id :guard Field?)] (do (assert-driver-supports :standard-deviation-aggregations)
(->Aggregation :stddev (ph field-id)))
["sum" (field-id :guard Field?)] (->Aggregation :sum (ph field-id))
["cum_sum" (field-id :guard Field?)] (->Aggregation :cumulative-sum (ph field-id)))
;; ## -------------------- Breakout --------------------
......
(ns metabase.models.card
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.api.common :refer [*current-user-id*]]
[metabase.db :refer :all]
(metabase.models [interface :refer :all]
......
(ns metabase.models.card-favorite
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.db :refer :all]
(metabase.models [card :refer [Card]]
[interface :refer :all]
......
(ns metabase.models.dashboard
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.db :refer :all]
(metabase.models [common :refer :all]
[dashboard-card :refer [DashboardCard]]
......
(ns metabase.models.dashboard-card
(:require [clojure.set :as set]
[korma.core :refer :all, :exclude [defentity]]
[korma.core :refer :all, :exclude [defentity update]]
[metabase.db :refer :all]
(metabase.models [card :refer [Card]]
[interface :refer :all])))
......
(ns metabase.models.database
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.api.common :refer [*current-user*]]
[metabase.db :refer :all]
[metabase.models.interface :refer :all]))
......
(ns metabase.models.field
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.api.common :refer [check]]
[metabase.db :refer :all]
(metabase.models [common :as common]
......
(ns metabase.models.field-values
(:require [clojure.tools.logging :as log]
[korma.core :refer :all, :exclude [defentity]]
[korma.core :refer :all, :exclude [defentity update]]
(metabase [db :refer :all]
[util :as u])
[metabase.models.interface :refer :all]))
......
(ns metabase.models.foreign-key
(:require [korma.core :refer :all, :exclude [defentity]]
(:require [korma.core :refer :all, :exclude [defentity update]]
[metabase.db :refer :all]
[metabase.models.interface :refer :all]))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment