diff --git a/frontend/src/metabase/admin/databases/database.js b/frontend/src/metabase/admin/databases/database.js
index 1be971f1f394479e5204937540e92d4f9a54f70c..d95039f6826b3d803caef1d2e101ead9bc321118 100644
--- a/frontend/src/metabase/admin/databases/database.js
+++ b/frontend/src/metabase/admin/databases/database.js
@@ -21,7 +21,7 @@ export const fetchDatabases = createThunkAction("FETCH_DATABASES", function() {
         try {
             return await MetabaseApi.db_list();
         } catch(error) {
-            console.log("error fetching databases", error);
+            console.error("error fetching databases", error);
         }
     };
 });
@@ -36,7 +36,7 @@ export const initializeDatabase = createThunkAction("INITIALIZE_DATABASE", funct
                 if (error.status == 404) {
                     //$location.path('/admin/databases/');
                 } else {
-                    console.log("error fetching database", databaseId, error);
+                    console.error("error fetching database", databaseId, error);
                 }
             }
         } else {
@@ -59,7 +59,7 @@ export const addSampleDataset = createThunkAction("ADD_SAMPLE_DATASET", function
             MetabaseAnalytics.trackEvent("Databases", "Add Sample Data");
             return sampleDataset;
         } catch(error) {
-            console.log("error adding sample dataset", error);
+            console.error("error adding sample dataset", error);
             return error;
         }
     };
@@ -90,7 +90,7 @@ export const saveDatabase = createThunkAction("SAVE_DATABASE", function(database
 
         } catch (error) {
             //$scope.$broadcast("form:api-error", error);
-            console.log("error saving database", error);
+            console.error("error saving database", error);
             MetabaseAnalytics.trackEvent("Databases", database.id ? "Update Failed" : "Create Failed", database.engine);
             formState = { formError: error };
         }
diff --git a/frontend/src/metabase/admin/people/reducers.js b/frontend/src/metabase/admin/people/reducers.js
index 14c1e2a1459cccb892e3e354665fee0e93392dea..2fc2e1a0dfa2d6fa91af0be4e7545ff5b0245817 100644
--- a/frontend/src/metabase/admin/people/reducers.js
+++ b/frontend/src/metabase/admin/people/reducers.js
@@ -24,5 +24,5 @@ export const users = handleActions({
     [DELETE_USER]: { next: (state, { payload: user }) => _.omit(state, user.id) },
     [GRANT_ADMIN]: { next: (state, { payload: user }) => ({ ...state, [user.id]: user }) },
     [REVOKE_ADMIN]: { next: (state, { payload: user }) => ({ ...state, [user.id]: user }) },
-    [UPDATE_USER]: { next: (state, { payload: user }) => ({ ...state, [user.id]: user }) },
+    [UPDATE_USER]: { next: (state, { payload: user }) => ({ ...state, [user.id]: user }) }
 }, null);
diff --git a/frontend/src/metabase/components/UserAvatar.jsx b/frontend/src/metabase/components/UserAvatar.jsx
index 33d4e96c8271095213a479d06f7d8c6f23c95a40..af24b4bcf6bc6986d78330e2d1f48d0d5cf1f21b 100644
--- a/frontend/src/metabase/components/UserAvatar.jsx
+++ b/frontend/src/metabase/components/UserAvatar.jsx
@@ -26,17 +26,13 @@ export default class UserAvatar extends Component {
     userInitials() {
         const { first_name, last_name } = this.props.user;
 
-        let initials = '??';
-
-        if (first_name !== 'undefined') {
-            initials = first_name.substring(0, 1).toUpperCase();
+        function initial(name) {
+            return typeof name !== 'undefined' && name.length ? name.substring(0, 1).toUpperCase() : '';
         }
 
-        if (last_name !== 'undefined') {
-            initials = initials + last_name.substring(0, 1).toUpperCase();
-        }
+        const initials = initial(first_name) + initial(last_name);
 
-        return initials;
+        return initials.length ? initials : '?';
     }
 
     render() {
diff --git a/frontend/src/metabase/lib/formatting.js b/frontend/src/metabase/lib/formatting.js
index 8093c5fc394949d32a9bdae3cb1db1a564b84941..3f0e5e66a2384183e4baf2e489fcfcba3a912cfb 100644
--- a/frontend/src/metabase/lib/formatting.js
+++ b/frontend/src/metabase/lib/formatting.js
@@ -13,7 +13,7 @@ const FIXED_NUMBER_FORMATTER_NO_COMMA = d3.format(".f");
 const DECIMAL_DEGREES_FORMATTER       = d3.format(".08f");
 
 export function formatNumber(number, options = {}) {
-    options = { comma: true, ...options}
+    options = { comma: true, ...options};
     if (options.compact) {
         return Humanize.compactInteger(number, 1);
     } else if (number > -1 && number < 1) {
@@ -102,7 +102,7 @@ export function formatValue(value, options = {}) {
         return value;
     } else if (typeof value === "number") {
         if (column && (column.special_type === "latitude" || column.special_type === "longitude")) {
-            return DECIMAL_DEGREES_FORMATTER(value)
+            return DECIMAL_DEGREES_FORMATTER(value);
         } else {
             return formatNumber(value, options);
         }
diff --git a/frontend/src/metabase/nav/containers/Navbar.jsx b/frontend/src/metabase/nav/containers/Navbar.jsx
index 45f04d3cca0698d982645df7dd738a126f0210a6..845b9b2691b7b0a6f36dd7cf8c8b6081f5a2e50c 100644
--- a/frontend/src/metabase/nav/containers/Navbar.jsx
+++ b/frontend/src/metabase/nav/containers/Navbar.jsx
@@ -23,6 +23,17 @@ const mapDispatchToProps = {
     onChangeLocation: push
 };
 
+const AdminNavItem = ({ name, path, currentPath }) =>
+    <li>
+        <Link
+            to={path}
+            data-metabase-event={"Navbar;" + name}
+            className={cx("NavItem py1 px2 no-decoration", {"is--selected": currentPath.startsWith(path) })}
+        >
+            {name}
+        </Link>
+    </li>
+
 @connect(mapStateToProps, mapDispatchToProps)
 export default class Navbar extends Component {
     static propTypes = {
@@ -57,10 +68,6 @@ export default class Navbar extends Component {
     }
 
     renderAdminNav() {
-        const getClasses = (path) => cx("NavItem py1 px2 no-decoration", {
-            "is--selected": this.isActive(path)
-        });
-
         return (
             <nav className={cx("Nav AdminNav", this.props.className)}>
                 <div className="wrapper flex align-center">
@@ -70,29 +77,13 @@ export default class Navbar extends Component {
                     </div>
 
                     <ul className="sm-ml4 flex flex-full">
-                        <li>
-                            <Link to="/admin/settings" data-metabase-event={"Navbar;Settings"} className={getClasses("/admin/settings")}  >
-                                Settings
-                            </Link>
-                        </li>
-                        <li>
-                            <Link to="/admin/people" data-metabase-event={"Navbar;People"} className={getClasses("/admin/people")} >
-                                People
-                            </Link>
-                        </li>
-                        <li>
-                            <Link to="/admin/datamodel/database" data-metabase-event={"Navbar;Data Model"} className={getClasses("/admin/datamodel")} >
-                                Data Model
-                            </Link>
-                        </li>
-                        <li>
-                            <Link to="/admin/databases" data-metabase-event={"Navbar;Databases"} className={getClasses("/admin/databases")}>
-                                Databases
-                            </Link>
-                        </li>
+                        <AdminNavItem name="Settings"    path="/admin/settings"     currentPath={this.props.path} />
+                        <AdminNavItem name="People"      path="/admin/people"       currentPath={this.props.path} />
+                        <AdminNavItem name="Data Model"  path="/admin/datamodel"    currentPath={this.props.path} />
+                        <AdminNavItem name="Databases"   path="/admin/databases"    currentPath={this.props.path} />
                     </ul>
 
-                    <ProfileLink {...this.props}></ProfileLink>
+                    <ProfileLink {...this.props} />
                 </div>
             </nav>
         );
diff --git a/frontend/src/metabase/services.js b/frontend/src/metabase/services.js
index 50cc9063c845f475375fb27e5ad60a5f0ddf10f1..bf0a26557c01e5eeea180be4d975e8d954cc7ca3 100644
--- a/frontend/src/metabase/services.js
+++ b/frontend/src/metabase/services.js
@@ -544,7 +544,7 @@ CoreServices.factory('Settings', ['$resource', function($resource) {
         list: {
             url: '/api/setting',
             method: 'GET',
-            isArray: true,
+            isArray: true
         },
         // POST endpoint handles create + update in this case
         put: {
diff --git a/src/metabase/api/card.clj b/src/metabase/api/card.clj
index 6a25c5d7abc930828f58456d38a8dd7664a8a7bf..0647e4d3ee06f2e7f588e5a4a884e9e008435030 100644
--- a/src/metabase/api/card.clj
+++ b/src/metabase/api/card.clj
@@ -1,7 +1,6 @@
 (ns metabase.api.card
   (:require [clojure.data :as data]
             [compojure.core :refer [GET POST DELETE PUT]]
-            [honeysql.helpers :as h]
             [metabase.api.common :refer :all]
             (metabase [db :as db]
                       [events :as events])
@@ -78,9 +77,9 @@
   (cards-with-ids (map :model_id (db/select [ViewLog :model_id [:%max.timestamp :max]]
                                    :model   "card"
                                    :user_id *current-user-id*
-                                   (-> (h/group :model_id)
-                                       (h/order-by [:max :desc])
-                                       (h/limit 10))))))
+                                   {:group-by [:model_id]
+                                    :order-by [[:max :desc]]
+                                    :limit    10}))))
 
 (defn- cards:popular
   "All `Cards`, sorted by popularity (the total number of times they are viewed in `ViewLogs`).
@@ -88,8 +87,8 @@
   []
   (cards-with-ids (map :model_id (db/select [ViewLog :model_id [:%count.* :count]]
                                    :model "card"
-                                   (-> (h/group :model_id)
-                                       (h/order-by [:count :desc]))))))
+                                   {:group-by [:model_id]
+                                    :order-by [[:count :desc]]}))))
 
 (defn- cards:archived
   "`Cards` that have been archived."
@@ -169,6 +168,7 @@
          (->> (events/publish-event :card-read))
          (dissoc :actor_id)))
 
+
 (defendpoint PUT "/:id"
   "Update a `Card`."
   [id :as {{:keys [dataset_query description display name public_perms visualization_settings archived], :as body} :body}]
@@ -198,6 +198,7 @@
                   :else                        :card-update)]
       (events/publish-event event (assoc (Card id) :actor_id *current-user-id*)))))
 
+
 (defendpoint DELETE "/:id"
   "Delete a `Card`."
   [id]
@@ -207,6 +208,7 @@
     (u/prog1 (db/cascade-delete! Card,:id id)
       (events/publish-event :card-delete (assoc card :actor_id *current-user-id*)))))
 
+
 (defendpoint GET "/:id/favorite"
   "Has current user favorited this `Card`?"
   [id]
@@ -218,12 +220,14 @@
   [card-id]
   (db/insert! CardFavorite :card_id card-id, :owner_id *current-user-id*))
 
+
 (defendpoint DELETE "/:card-id/favorite"
   "Unfavorite a Card."
   [card-id]
   (let-404 [id (db/select-one-id CardFavorite :card_id card-id, :owner_id *current-user-id*)]
     (db/cascade-delete! CardFavorite, :id id)))
 
+
 (defendpoint POST "/:card-id/labels"
   "Update the set of `Labels` that apply to a `Card`."
   [card-id :as {{:keys [label_ids]} :body}]
@@ -235,7 +239,6 @@
       (db/cascade-delete! CardLabel, :label_id [:in labels-to-remove], :card_id card-id))
     (doseq [label-id labels-to-add]
       (db/insert! CardLabel :label_id label-id, :card_id card-id)))
-  ;; TODO - Should this endpoint return something more useful instead ?
   {:status :ok})
 
 (define-routes)
diff --git a/src/metabase/api/common.clj b/src/metabase/api/common.clj
index f1bfdb404d3850e20c27613bbf5c2a94ebe7c260..42219830ac7b15bc954b2fda5ffaa3810eb4000f 100644
--- a/src/metabase/api/common.clj
+++ b/src/metabase/api/common.clj
@@ -17,7 +17,7 @@
 ;;; ## DYNAMIC VARIABLES
 ;; These get bound by middleware for each HTTP request.
 
-(def ^:dynamic *current-user-id*
+(def ^:dynamic ^Integer *current-user-id*
   "Int ID or `nil` of user associated with current API call."
   nil)
 
@@ -26,6 +26,10 @@
    ex. `@*current-user*`"
   (atom nil)) ; default binding is just something that will return nil when dereferenced
 
+(def ^:dynamic ^Boolean *is-superuser?*
+  "Is the current user a superuser?"
+  false)
+
 
 ;;; ## CONDITIONAL RESPONSE FUNCTIONS / MACROS
 
@@ -64,17 +68,17 @@
 (defn check-superuser
   "Check that `*current-user*` is a superuser or throw a 403."
   []
-  (check-403 (db/exists? 'User, :id *current-user-id*, :is_superuser true)))
+  (check-403 *is-superuser?*))
 
 
 ;;; #### checkp- functions: as in "check param". These functions expect that you pass a symbol so they can throw exceptions w/ relevant error messages.
 
-(defn invalid-param-exception
-  "Create an `ExceptionInfo` that contains information about an invalid API params in the expected format."
+(defn throw-invalid-param-exception
+  "Throw an `ExceptionInfo` that contains information about an invalid API params in the expected format."
   [field-name message]
-  (ex-info (format "Invalid field: %s" field-name)
+  (throw (ex-info (format "Invalid field: %s" field-name)
            {:status-code 400
-            :errors      {(keyword field-name) message}}))
+            :errors      {(keyword field-name) message}})))
 
 (defn checkp
   "Assertion mechanism for use inside API functions that validates individual input params.
@@ -87,7 +91,7 @@
       (checkp test field-name message)"
   ([tst field-name message]
    (when-not tst
-     (throw (invalid-param-exception (str field-name) message)))))
+     (throw-invalid-param-exception (str field-name) message))))
 
 (defn checkp-with
   "Check (F VALUE), or throw an exception with STATUS-CODE (default is 400).
@@ -287,8 +291,9 @@
 (defannotation Required
   "Param may not be `nil`."
   [symb value]
-  (or value
-      (throw (invalid-param-exception (name symb) "field is a required param."))))
+  (u/prog1 value
+    (when (nil? value)
+      (throw-invalid-param-exception (name symb) "field is a required param."))))
 
 (defannotation Date
   "Parse param string as an [ISO 8601 date](http://en.wikipedia.org/wiki/ISO_8601), e.g.
@@ -296,7 +301,7 @@
   [symb value :nillable]
   (try (u/->Timestamp value)
        (catch Throwable _
-         (throw (invalid-param-exception (name symb) (format "'%s' is not a valid date." value))))))
+         (throw-invalid-param-exception (name symb) (format "'%s' is not a valid date." value)))))
 
 (defannotation String->Integer
   "Param is converted from a string to an integer."
@@ -319,7 +324,7 @@
     (= value "true")  true
     (= value "false") false
     (nil? value)      nil
-    :else             (throw (invalid-param-exception (name symb) (format "'%s' is not a valid boolean." value)))))
+    :else             (throw-invalid-param-exception (name symb) (format "'%s' is not a valid boolean." value))))
 
 (defannotation Integer
   "Param must be an integer (this does *not* cast the param)."
@@ -340,13 +345,19 @@
   "Param must be an array of integers (this does *not* cast the param)."
   [symb value :nillable]
   (checkp-with vector? symb value "value must be an array.")
-  (mapv (fn [v] (checkp-with integer? symb v "array value must be an integer.")) value))
+  (mapv #(checkp-with integer? symb % "array value must be a integer.") value))
+
+(defannotation ArrayOfStrings
+  "Param must be an array of strings (this does *not* cast the param)."
+  [symb value :nillable]
+  (checkp-with vector? symb value "value must be an array.")
+  (mapv #(checkp-with string? symb % "array value must be a string.") value))
 
 (defannotation ArrayOfMaps
   "Param must be an array of maps (this does *not* cast the param)."
   [symb value :nillable]
   (checkp-with vector? symb value "value must be an array.")
-  (mapv (fn [v] (checkp-with map? symb v "array value must be a map.")) value))
+  (mapv #(checkp-with map? symb % "array value must be a map.") value))
 
 (defannotation NonEmptyString
   "Param must be a non-empty string (strings that only contain whitespace are considered empty)."
diff --git a/src/metabase/api/dataset.clj b/src/metabase/api/dataset.clj
index 01c3853d9c4f305fed9c40c555e78acd7d71123e..9a3263516c3dc3ebe8bb05814d947f47d40fe27d 100644
--- a/src/metabase/api/dataset.clj
+++ b/src/metabase/api/dataset.clj
@@ -9,36 +9,36 @@
                              [database :refer [Database]]
                              [hydrate :refer [hydrate]]
                              [query-execution :refer [QueryExecution]])
-            [metabase.query-processor :as qp]
-            [metabase.util :as u]))
+            (metabase [query-processor :as qp]
+                      [util :as u])))
 
-(def ^:private ^:const api-max-results-bare-rows
+(def ^:private ^:const max-results-bare-rows
   "Maximum number of rows to return specifically on :rows type queries via the API."
   2000)
 
-(def ^:private ^:const api-max-results
+(def ^:private ^:const max-results
   "General maximum number of rows to return from an API query."
   10000)
 
-(def ^:const dataset-query-api-constraints
+(def ^:const query-constraints
   "Default map of constraints that we apply on dataset queries executed by the api."
-  {:max-results           api-max-results
-   :max-results-bare-rows api-max-results-bare-rows})
+  {:max-results           max-results
+   :max-results-bare-rows max-results-bare-rows})
 
 (defendpoint POST "/"
   "Execute an MQL query and retrieve the results as JSON."
   [:as {{:keys [database] :as body} :body}]
   (read-check Database database)
   ;; add sensible constraints for results limits on our query
-  (let [query (assoc body :constraints dataset-query-api-constraints)]
-    (qp/dataset-query query {:executed_by *current-user-id*})))
+  (let [query (assoc body :constraints query-constraints)]
+    (qp/dataset-query query {:executed-by *current-user-id*})))
 
  (defendpoint POST "/duration"
    "Get historical query execution duration."
    [:as {{:keys [database] :as body} :body}]
    (read-check Database database)
    ;; add sensible constraints for results limits on our query
-   (let [query         (assoc body :constraints dataset-query-api-constraints)
+   (let [query         (assoc body :constraints query-constraints)
          running-times (db/select-field :running_time QueryExecution
                          :query_hash (hash query)
                          {:order-by [[:started_at :desc]]
@@ -53,7 +53,7 @@
   [query]
   {query [Required String->Dict]}
   (read-check Database (:database query))
-  (let [{{:keys [columns rows]} :data :keys [status] :as response} (qp/dataset-query query {:executed_by *current-user-id*})
+  (let [{{:keys [columns rows]} :data :keys [status] :as response} (qp/dataset-query query {:executed-by *current-user-id*})
         columns (map name columns)] ; turn keywords into strings, otherwise we get colons in our output
     (if (= status :completed)
       ;; successful query, send CSV file
@@ -77,8 +77,8 @@
     (read-check Database (:database dataset_query))
     ;; add sensible constraints for results limits on our query
     ;; TODO: it would be nice to associate the card :id with the query execution tracking
-    (let [query   (assoc dataset_query :constraints dataset-query-api-constraints)
-          options {:executed_by *current-user-id*}]
+    (let [query   (assoc dataset_query :constraints query-constraints)
+          options {:executed-by *current-user-id*}]
       {:card   (hydrate card :creator)
        :result (qp/dataset-query query options)})))
 
diff --git a/src/metabase/api/pulse.clj b/src/metabase/api/pulse.clj
index bb02dec225f085780163d85226889dc2449bb256..ce6a11254d61b086c302639b6aff04072d1e48b8 100644
--- a/src/metabase/api/pulse.clj
+++ b/src/metabase/api/pulse.clj
@@ -31,7 +31,7 @@
    channels [Required ArrayOfMaps]}
   ;; prevent more than 5 cards
   ;; limit channel types to :email and :slack
-  (check-500 (pulse/create-pulse name *current-user-id* (filter identity (map :id cards)) channels)))
+  (check-500 (pulse/create-pulse! name *current-user-id* (filter identity (map :id cards)) channels)))
 
 
 (defendpoint GET "/:id"
@@ -86,7 +86,7 @@
   [id]
   (let [card (Card id)]
     (read-check Database (:database (:dataset_query card)))
-    (let [result (qp/dataset-query (:dataset_query card) {:executed_by *current-user-id*})]
+    (let [result (qp/dataset-query (:dataset_query card) {:executed-by *current-user-id*})]
       {:status 200, :body (html [:html [:body {:style "margin: 0;"} (binding [render/*include-title* true
                                                                               render/*include-buttons* true]
                                                                       (render/render-pulse-card card result))]])})))
@@ -96,7 +96,7 @@
   [id]
   (let [card (Card id)]
     (read-check Database (:database (:dataset_query card)))
-    (let [result    (qp/dataset-query (:dataset_query card) {:executed_by *current-user-id*})
+    (let [result    (qp/dataset-query (:dataset_query card) {:executed-by *current-user-id*})
           data      (:data result)
           card-type (render/detect-pulse-card-type card data)
           card-html (html (binding [render/*include-title* true]
@@ -111,7 +111,7 @@
   [id]
   (let [card (Card id)]
     (read-check Database (:database (:dataset_query card)))
-    (let [result (qp/dataset-query (:dataset_query card) {:executed_by *current-user-id*})
+    (let [result (qp/dataset-query (:dataset_query card) {:executed-by *current-user-id*})
           ba   (binding [render/*include-title* true]
                  (render/render-pulse-card-to-png card result))]
       {:status 200, :headers {"Content-Type" "image/png"}, :body (new java.io.ByteArrayInputStream ba) })))
diff --git a/src/metabase/api/session.clj b/src/metabase/api/session.clj
index 801913b20e3014b1121e6dfd3d535388cf775ecb..a04b81025bc1852b446fc16bf93c4f40f039e96b 100644
--- a/src/metabase/api/session.clj
+++ b/src/metabase/api/session.clj
@@ -112,7 +112,7 @@
         ;; after a successful password update go ahead and offer the client a new session that they can use
         {:success    true
          :session_id (create-session! user)})
-      (throw (invalid-param-exception :password "Invalid reset token"))))
+      (throw-invalid-param-exception :password "Invalid reset token")))
 
 
 (defendpoint GET "/password_reset_token_valid"
diff --git a/src/metabase/api/tiles.clj b/src/metabase/api/tiles.clj
index 62afdc0b8cec4f3ca3da4f92214ce0691110f98a..ac78a149b49592fd7b8cb2915d181d48cb7ba62d 100644
--- a/src/metabase/api/tiles.clj
+++ b/src/metabase/api/tiles.clj
@@ -119,7 +119,7 @@
    lon-col-idx String->Integer
    query       String->Dict}
   (let [updated-query (update query :query #(query-with-inside-filter % lat-field lon-field x y zoom))
-        result        (qp/dataset-query updated-query {:executed_by   *current-user-id*
+        result        (qp/dataset-query updated-query {:executed-by   *current-user-id*
                                                        :synchronously true})
         points        (for [row (-> result :data :rows)]
                         [(nth row lat-col-idx) (nth row lon-col-idx)])]
diff --git a/src/metabase/cmd/load_from_h2.clj b/src/metabase/cmd/load_from_h2.clj
index e548ed80646f7dea562001775b15c75f3e875df9..6774154deb6fc2e712821ae2d513c394c7cc732a 100644
--- a/src/metabase/cmd/load_from_h2.clj
+++ b/src/metabase/cmd/load_from_h2.clj
@@ -25,8 +25,8 @@
                              [pulse-channel :refer [PulseChannel]]
                              [pulse-channel-recipient :refer [PulseChannelRecipient]]
                              [query-execution :refer [QueryExecution]]
-                             [raw-table :refer [RawTable]]
                              [raw-column :refer [RawColumn]]
+                             [raw-table :refer [RawTable]]
                              [revision :refer [Revision]]
                              [segment :refer [Segment]]
                              [session :refer [Session]]
diff --git a/src/metabase/db.clj b/src/metabase/db.clj
index 96e317bc579bd8372acd02c01c9a0aa717f4590f..ddffb5409c1d36ce805232b58f22a1bc8deb8697 100644
--- a/src/metabase/db.clj
+++ b/src/metabase/db.clj
@@ -1,6 +1,7 @@
 (ns metabase.db
   "Database definition and helper functions for interacting with the database."
-  (:require [clojure.java.jdbc :as jdbc]
+  (:require (clojure.java [io :as io]
+                          [jdbc :as jdbc])
             [clojure.tools.logging :as log]
             (clojure [set :as set]
                      [string :as s]
@@ -33,7 +34,7 @@
            "mem:metabase;DB_CLOSE_DELAY=-1"
            ;; File-based DB
            (let [db-file-name (config/config-str :mb-db-file)
-                 db-file      (clojure.java.io/file db-file-name)
+                 db-file      (io/file db-file-name)
                  options      ";AUTO_SERVER=TRUE;MV_STORE=FALSE;DB_CLOSE_DELAY=-1"]
              (apply str "file:" (if (.isAbsolute db-file)
                                   ;; when an absolute path is given for the db file then don't mess with it
@@ -368,6 +369,8 @@
   (jdbc/query (db-connection) (honeysql->sql honeysql-form) options))
 
 
+;; TODO - wouldn't it be *pretty cool* if we just made entities implement the honeysql.format/ToSql protocol so we didn't need this function?
+;;        That would however mean we would have to make sure the entities are resolved first
 (defn entity->table-name
   "Get the keyword table name associated with an ENTITY, which can be anything that can be passed to `resolve-entity`.
 
@@ -561,7 +564,7 @@
     :mysql    :generated_key
     :h2       (keyword "scope_identity()")))
 
-(defn simple-insert-many!
+(defn- simple-insert-many!
   "Do a simple JDBC `insert!` of multiple objects into the database.
    Normally you should use `insert-many!` instead, which calls the entity's `pre-insert` method on the ROW-MAPS;
    `simple-insert-many!` is offered for cases where you'd like to specifically avoid this behavior.
@@ -579,6 +582,7 @@
 (defn insert-many!
   "Insert several new rows into the Database. Resolves ENTITY, and calls `pre-insert` on each of the ROW-MAPS.
    Returns a sequence of the IDs of the newly created objects.
+   Note: this *does not* call `post-insert` on newly created objects. If you need `post-insert` behavior, use `insert!` instead.
 
      (db/insert-many! 'Label [{:name \"Toucan Friendly\"}
                               {:name \"Bird Approved\"}]) -> [38 39]"
@@ -588,11 +592,9 @@
     (simple-insert-many! entity (for [row-map row-maps]
                                   (models/do-pre-insert entity row-map)))))
 
-(defn simple-insert!
-  "Do a simple JDBC `insert!` of a single object.
-   Normally you should use `insert!` instead, which calls the entity's `pre-insert` method on ROW-MAP;
-   `simple-insert!` is offered for cases where you'd like to specifically avoid this behavior.
-   Returns the ID of the inserted object.
+(defn- simple-insert!
+  "Do a simple JDBC `insert` of a single object.
+   This is similar to `insert!` but returns the ID of the newly created object rather than the object itself, and does not call `post-insert`.
 
      (db/simple-insert! 'Label :name \"Toucan Friendly\") -> 1
 
@@ -605,8 +607,8 @@
    (simple-insert! entity (apply array-map k v more))))
 
 (defn insert!
-  "Insert a new object into the Database. Resolves ENTITY, and calls its `pre-insert` method on ROW-MAP to prepare it before insertion;
-   after insert, it fetches and returns the newly created object.
+  "Insert a new object into the Database. Resolves ENTITY, calls its `pre-insert` method on ROW-MAP to prepare it before insertion;
+   after insert, it fetches and the newly created object, passes it to `post-insert`, and returns the results.
    For flexibility, `insert!` can handle either a single map or individual kwargs:
 
      (db/insert! Label {:name \"Toucan Unfriendly\"})
@@ -616,7 +618,7 @@
    {:pre [(map? row-map) (every? keyword? (keys row-map))]}
    (let [entity (resolve-entity entity)]
      (when-let [id (simple-insert! entity (models/do-pre-insert entity row-map))]
-       (entity id))))
+       (models/post-insert (entity id)))))
   ([entity k v & more]
    (insert! entity (apply array-map k v more))))
 
@@ -723,6 +725,7 @@
   "Easy way to see if something exists in the DB.
     (db/exists? User :id 100)
    NOTE: This only works for objects that have an `:id` field."
+  {:style/indent 1}
   ^Boolean [entity & kvs]
   (boolean (select-one entity (apply where (h/select {} :id) kvs))))
 
diff --git a/src/metabase/middleware.clj b/src/metabase/middleware.clj
index e2498d8024f939372027b407e18fe603fb26c023..514f3b30689e5e423a40e7b557d22338cfec8910 100644
--- a/src/metabase/middleware.clj
+++ b/src/metabase/middleware.clj
@@ -3,9 +3,9 @@
   (:require [clojure.tools.logging :as log]
             (cheshire factory
                       [generate :refer [add-encoder encode-str encode-nil]])
-            [metabase.api.common :refer [*current-user* *current-user-id*]]
-            [metabase.config :as config]
-            [metabase.db :as db]
+            [metabase.api.common :refer [*current-user* *current-user-id* *is-superuser?*]]
+            (metabase [config :as config]
+                      [db :as db])
             (metabase.models [interface :as models]
                              [session :refer [Session]]
                              [setting :refer [defsetting]]
@@ -60,14 +60,18 @@
   (fn [{:keys [metabase-session-id] :as request}]
     ;; TODO - what kind of validations can we do on the sessionid to make sure it's safe to handle?  str?  alphanumeric?
     (handler (or (when (and metabase-session-id ((resolve 'metabase.core/initialized?)))
-                   (when-let [session (db/select-one [Session :created_at :user_id]
+                   (when-let [session (db/select-one [Session :created_at :user_id (db/qualify User :is_superuser)]
                                         (db/join [Session :user_id] [User :id])
                                         (db/qualify User :is_active) true
                                         (db/qualify Session :id) metabase-session-id)]
-                     (let [session-age-ms (- (System/currentTimeMillis) (.getTime ^java.util.Date (get session :created_at (u/->Date 0))))]
+                     (let [session-age-ms (- (System/currentTimeMillis) (or (when-let [^java.util.Date created-at (:created_at session)]
+                                                                              (.getTime created-at))
+                                                                            0))]
                        ;; If the session exists and is not expired (max-session-age > session-age) then validation is good
                        (when (and session (> (config/config-int :max-session-age) (quot session-age-ms 60000)))
-                         (assoc request :metabase-user-id (:user_id session))))))
+                         (assoc request
+                           :metabase-user-id (:user_id session)
+                           :is-superuser?    (:is_superuser session))))))
                  request))))
 
 
@@ -79,6 +83,9 @@
       (handler request)
       response-unauthentic)))
 
+(def ^:private current-user-fields
+  (vec (concat [User :is_active :is_staff :google_auth] (models/default-fields User))))
+
 (defn bind-current-user
   "Middleware that binds `metabase.api.common/*current-user*` and `*current-user-id*`
 
@@ -88,9 +95,8 @@
   (fn [request]
     (if-let [current-user-id (:metabase-user-id request)]
       (binding [*current-user-id* current-user-id
-                *current-user*    (delay (db/select-one (vec (concat [User :is_active :is_staff :google_auth]
-                                                                     (models/default-fields User)))
-                                           :id current-user-id))]
+                *is-superuser?*   (:is-superuser? request)
+                *current-user*    (delay (db/select-one current-user-fields, :id current-user-id))]
         (handler request))
       (handler request))))
 
@@ -100,9 +106,9 @@
    We check the request headers for `X-METABASE-APIKEY` and if it's not found then then no keyword is bound to the request."
   [handler]
   (fn [{:keys [headers] :as request}]
-    (if-let [api-key (headers metabase-api-key-header)]
-      (handler (assoc request :metabase-api-key api-key))
-      (handler request))))
+    (handler (if-let [api-key (headers metabase-api-key-header)]
+               (assoc request :metabase-api-key api-key)
+               request))))
 
 
 (defn enforce-api-key
diff --git a/src/metabase/models/database.clj b/src/metabase/models/database.clj
index b84259fa6adb8bb56c083ff6d79fbe60464c673c..b51e2f8f0a1ff009b13b1b72d2d069a8b46cba45 100644
--- a/src/metabase/models/database.clj
+++ b/src/metabase/models/database.clj
@@ -1,5 +1,6 @@
 (ns metabase.models.database
-  (:require [cheshire.generate :refer [add-encoder encode-map]]
+  (:require [clojure.string :as s]
+            [cheshire.generate :refer [add-encoder encode-map]]
             [metabase.api.common :refer [*current-user*]]
             [metabase.db :as db]
             [metabase.models.interface :as i]
@@ -9,6 +10,7 @@
   "The string to replace passwords with when serializing Databases."
   "**MetabasePass**")
 
+
 (i/defentity Database :metabase_database)
 
 (defn- post-select [{:keys [engine] :as database}]
@@ -39,6 +41,23 @@
           :pre-cascade-delete pre-cascade-delete}))
 
 
+(defn schema-names
+  "Return a *sorted set* of schema names (as strings) associated with this `Database`."
+  [{:keys [id]}]
+  (when id
+    (apply sorted-set (sort-by (fn [schema-name]
+                                 (when schema-name
+                                   (s/lower-case schema-name)))
+                               (db/select-field :schema 'Table
+                                 :db_id id
+                                 {:modifiers [:DISTINCT]})))))
+
+(defn schema-exists?
+  "Does DATABASE have any tables with SCHEMA?"
+  ^Boolean [{:keys [id]}, schema]
+  (db/exists? 'Table :db_id id, :schema (some-> schema name)))
+
+
 (add-encoder DatabaseInstance (fn [db json-generator]
                                 (encode-map (cond
                                               (not (:is_superuser @*current-user*)) (dissoc db :details)
diff --git a/src/metabase/models/interface.clj b/src/metabase/models/interface.clj
index 688f9f5f6eb05e884f240817e3c683906dfd651f..daeebbf7f2de9737d0e810a207baf27eb4996f97 100644
--- a/src/metabase/models/interface.clj
+++ b/src/metabase/models/interface.clj
@@ -44,10 +44,22 @@
     "Gets called by `insert!` immediately before inserting a new object immediately before the SQL `INSERT` call.
      This provides an opportunity to do things like encode JSON or provide default values for certain fields.
 
-         (pre-insert [_ query]
+         (pre-insert [query]
            (let [defaults {:version 1}]
              (merge defaults query))) ; set some default values")
 
+  (post-insert [this]
+    "Gets called by `insert!` with an object that was newly inserted into the database.
+     This provides an opportunity to trigger specific logic that should occur when an object is inserted or modify the object that is returned.
+     The value returned by this method is returned to the caller of `insert!`. The default implementation is `identity`.
+
+       (post-insert [user]
+         (assoc user :newly-created true))
+
+       (post-insert [user]
+         (u/prog1 user
+           (add-user-to-magic-perm-groups! <>)))")
+
   (pre-update [this]
     "Called by `update!` before DB operations happen. A good place to set updated values for fields like `updated_at`.")
 
@@ -62,7 +74,7 @@
 
      The output of this function is ignored.
 
-        (pre-cascade-delete [_ {database-id :id :as database}]
+        (pre-cascade-delete [{database-id :id :as database}]
           (cascade-delete! Card :database_id database-id)
           ...)")
 
@@ -178,6 +190,7 @@
    :can-read?          (fn [this & _] (throw (UnsupportedOperationException. (format "No implementation of can-read? for %s; please provide one."  (class this)))))
    :can-write?         (fn [this & _] (throw (UnsupportedOperationException. (format "No implementation of can-write? for %s; please provide one." (class this)))))
    :pre-insert         identity
+   :post-insert        identity
    :pre-update         identity
    :post-select        identity
    :pre-cascade-delete (constantly nil)})
diff --git a/src/metabase/models/pulse.clj b/src/metabase/models/pulse.clj
index e25d4590a4a98a300cb9a96a24787f66f4a1ed6c..c202ad562632a92ed731b8451da8be5bb4138fa6 100644
--- a/src/metabase/models/pulse.clj
+++ b/src/metabase/models/pulse.clj
@@ -148,8 +148,7 @@
     (->> (retrieve-pulse id)
          (events/publish-event :pulse-update))))
 
-;; TODO - rename to `create-pulse!`
-(defn create-pulse
+(defn create-pulse!
   "Create a new `Pulse` by inserting it into the database along with all associated pieces of data such as:
   `PulseCards`, `PulseChannels`, and `PulseChannelRecipients`.
 
diff --git a/src/metabase/models/table.clj b/src/metabase/models/table.clj
index 991c816bd2e03692061cc9670e2294d0c5b82ad2..661e5fae17248e7e8fa6b28566ff411cadeb7844 100644
--- a/src/metabase/models/table.clj
+++ b/src/metabase/models/table.clj
@@ -105,6 +105,7 @@
     (db/update-where! Field {:table_id [:in table-ids]}
       :visibility_type "retired")))
 
+;; TODO - rename to `update-table-from-tabledef!`
 (defn update-table!
   "Update `Table` with the data from TABLE-DEF."
   [{:keys [id display_name], :as existing-table} {table-name :name}]
@@ -118,6 +119,7 @@
     ;; always return the table when we are done
     updated-table))
 
+;; TODO - rename to `create-table-from-tabledef!`
 (defn create-table!
   "Create `Table` with the data from TABLE-DEF."
   [database-id {schema-name :schema, table-name :name, raw-table-id :raw-table-id, visibility-type :visibility-type}]
diff --git a/src/metabase/models/user.clj b/src/metabase/models/user.clj
index f305f30b7e7d817fba61796304fd56b5cb8915ce..cdb44e3e5f1511decad500f527018ac309f99b89 100644
--- a/src/metabase/models/user.clj
+++ b/src/metabase/models/user.clj
@@ -12,7 +12,8 @@
 (i/defentity User :core_user)
 
 (defn- pre-insert [{:keys [email password reset_token] :as user}]
-  (assert (u/is-email? email))
+  (assert (u/is-email? email)
+    (format "Not a valid email: '%s'" email))
   (assert (and (string? password)
                (not (s/blank? password))))
   (assert (not (:password_salt user))
diff --git a/src/metabase/pulse.clj b/src/metabase/pulse.clj
index 026d9c65cd49cc039e31fc19bd3e132a97817497..a43fb49dd77199100eea3f73585784e397ddda0c 100644
--- a/src/metabase/pulse.clj
+++ b/src/metabase/pulse.clj
@@ -25,7 +25,7 @@
   (when-let [card (Card card-id)]
     (let [{:keys [creator_id dataset_query]} card]
       (try
-        {:card card :result (qp/dataset-query dataset_query {:executed_by creator_id})}
+        {:card card :result (qp/dataset-query dataset_query {:executed-by creator_id})}
         (catch Throwable t
           (log/warn (format "Error running card query (%n)" card-id) t))))))
 
diff --git a/src/metabase/query_processor.clj b/src/metabase/query_processor.clj
index 0f013a825eb5d83dc9291ad2cd67e3d5cc4aea3b..24f1514092931cdd17d4115cc34010d9eec61f0e 100644
--- a/src/metabase/query_processor.clj
+++ b/src/metabase/query_processor.clj
@@ -575,14 +575,14 @@
 
   Possible caller-options include:
 
-    :executed_by [int]  (user_id of caller)"
+    :executed-by [int]  (user_id of caller)"
   {:arglists '([query options])}
-  [query {:keys [executed_by]}]
-  {:pre [(integer? executed_by)]}
+  [query {:keys [executed-by]}]
+  {:pre [(integer? executed-by)]}
   (let [query-uuid      (str (java.util.UUID/randomUUID))
         query-hash      (hash query)
         query-execution {:uuid              query-uuid
-                         :executor_id       executed_by
+                         :executor_id       executed-by
                          :json_query        query
                          :query_hash        query-hash
                          :query_id          nil
@@ -598,7 +598,7 @@
                          :raw_query         ""
                          :additional_info   ""
                          :start_time_millis (System/currentTimeMillis)}
-        query           (assoc query :info {:executed-by executed_by
+        query           (assoc query :info {:executed-by executed-by
                                             :uuid        query-uuid
                                             :query-hash  query-hash
                                             :query-type  (if (mbql-query? query) "MBQL" "native")})]
@@ -651,8 +651,7 @@
   [{:keys [id], :as query-execution}]
   (if id
     ;; execution has already been saved, so update it
-    (do
-      (db/update! QueryExecution id query-execution)
-      query-execution)
+    (u/prog1 query-execution
+      (db/update! QueryExecution id query-execution))
     ;; first time saving execution, so insert it
     (db/insert! QueryExecution query-execution)))
diff --git a/src/metabase/util/password.clj b/src/metabase/util/password.clj
index d96cdbd7f62a8fe4e805bcc2ca463f86035cc4cb..8d4beb33efcb405b16a2e079855133eeffdaaf0d 100644
--- a/src/metabase/util/password.clj
+++ b/src/metabase/util/password.clj
@@ -1,6 +1,7 @@
 (ns metabase.util.password
   (:require [cemerick.friend.credentials :as creds]
-            [metabase.config :as config]))
+            (metabase [config :as config]
+                      [util :as u])))
 
 
 (defn- count-occurrences
@@ -58,10 +59,8 @@
 
 
 (defn verify-password
-  "Verify if a given unhashed password + salt matches the supplied hashed-password.  Returns true if matched, false otherwise."
-  [password salt hashed-password]
-  (try
-    (creds/bcrypt-verify (str salt password) hashed-password)
-    (catch Throwable e
-      ;; we wrap the friend/bcrypt-verify with this function specifically to avoid unintended exceptions getting out
-      false)))
+  "Verify if a given unhashed password + salt matches the supplied hashed-password. Returns `true` if matched, `false` otherwise."
+  ^Boolean [password salt hashed-password]
+  ;; we wrap the friend/bcrypt-verify with this function specifically to avoid unintended exceptions getting out
+  (boolean (u/ignore-exceptions
+             (creds/bcrypt-verify (str salt password) hashed-password))))
diff --git a/test/metabase/api/dataset_test.clj b/test/metabase/api/dataset_test.clj
index 065f5049c503862c5b7630bb2f7cd273b21941d5..5adc59629783c18a1e4b9b978680d5c0322b8aba 100644
--- a/test/metabase/api/dataset_test.clj
+++ b/test/metabase/api/dataset_test.clj
@@ -2,7 +2,7 @@
   "Unit tests for /api/dataset endpoints."
   (:require [clojure.string :as s]
             [expectations :refer :all]
-            [metabase.api.dataset :refer [dataset-query-api-constraints]]
+            [metabase.api.dataset :refer [query-constraints]]
             [metabase.db :as db]
             (metabase.models [card :refer [Card]]
                              [query-execution :refer [QueryExecution]])
@@ -65,7 +65,7 @@
                                (ql/aggregation (ql/count))))
                       (assoc :type "query")
                       (assoc-in [:query :aggregation] {:aggregation-type "count"})
-                      (assoc :constraints dataset-query-api-constraints))
+                      (assoc :constraints query-constraints))
     :started_at   true
     :finished_at  true
     :running_time true}
@@ -81,7 +81,7 @@
                                (ql/aggregation (ql/count))))
                       (assoc :type "query")
                       (assoc-in [:query :aggregation] {:aggregation-type "count"})
-                      (assoc :constraints dataset-query-api-constraints))
+                      (assoc :constraints query-constraints))
     :started_at   true
     :finished_at  true
     :running_time true
@@ -108,7 +108,7 @@
                 :json_query   {:database    (id)
                                :type        "native"
                                :native      {:query "foobar"}
-                               :constraints dataset-query-api-constraints}
+                               :constraints query-constraints}
                 :started_at   true
                 :finished_at  true
                 :running_time true}]
@@ -163,7 +163,7 @@
                                    (ql/aggregation (ql/count))))
                                (assoc :type "query")
                                (assoc-in [:query :aggregation] {:aggregation-type "count"})
-                               (assoc :constraints dataset-query-api-constraints))
+                               (assoc :constraints query-constraints))
              :started_at   true
              :finished_at  true
              :running_time true}}
@@ -179,7 +179,7 @@
                           (ql/aggregation (ql/count))))
                       (assoc :type "query")
                       (assoc-in [:query :aggregation] {:aggregation-type "count"})
-                      (assoc :constraints dataset-query-api-constraints))
+                      (assoc :constraints query-constraints))
     :started_at   true
     :finished_at  true
     :running_time true
diff --git a/test/metabase/api/pulse_test.clj b/test/metabase/api/pulse_test.clj
index 236ef6a80292ad3b3c692a882bec7f06bb6b28b6..8fd015f68e944b23ac72f5d3097e87a722d5706c 100644
--- a/test/metabase/api/pulse_test.clj
+++ b/test/metabase/api/pulse_test.clj
@@ -7,7 +7,7 @@
             (metabase.models [card :refer [Card]]
                              [common :as common]
                              [database :refer [Database]]
-                             [pulse :refer [Pulse create-pulse], :as pulse])
+                             [pulse :refer [Pulse], :as pulse])
             [metabase.test.data :refer :all]
             [metabase.test.data.users :refer :all]
             [metabase.test.util :as tu]
diff --git a/test/metabase/middleware_test.clj b/test/metabase/middleware_test.clj
index 199ce66b4358614a4c98c02389bf23c293101c8b..ec0e6923650053155930d2e67b7b1aca3bdaa2e1 100644
--- a/test/metabase/middleware_test.clj
+++ b/test/metabase/middleware_test.clj
@@ -8,6 +8,7 @@
             [metabase.models.session :refer [Session]]
             [metabase.test.data :refer :all]
             [metabase.test.data.users :refer :all]
+            [metabase.test.util :as tu]
             [metabase.util :as u]))
 
 ;;  ===========================  TEST wrap-session-id middleware  ===========================
@@ -62,11 +63,14 @@
 (defn- random-session-id []
   (str (java.util.UUID/randomUUID)))
 
+
+(tu/resolve-private-fns metabase.db simple-insert!)
+
 ;; valid session ID
 (expect
   (user->id :rasta)
   (let [session-id (random-session-id)]
-    (db/simple-insert! Session, :id session-id, :user_id (user->id :rasta), :created_at (u/new-sql-timestamp))
+    (simple-insert! Session, :id session-id, :user_id (user->id :rasta), :created_at (u/new-sql-timestamp))
     (-> (auth-enforced-handler (request-with-session-id session-id))
         :metabase-user-id)))
 
@@ -77,7 +81,7 @@
 (expect
   response-unauthentic
   (let [session-id (random-session-id)]
-    (db/simple-insert! Session, :id session-id, :user_id (user->id :rasta), :created_at (java.sql.Timestamp. 0))
+    (simple-insert! Session, :id session-id, :user_id (user->id :rasta), :created_at (java.sql.Timestamp. 0))
     (auth-enforced-handler (request-with-session-id session-id))))
 
 
@@ -87,7 +91,7 @@
 ;; NOTE that :trashbird is our INACTIVE test user
 (expect response-unauthentic
   (let [session-id (random-session-id)]
-    (db/simple-insert! Session, :id session-id, :user_id (user->id :trashbird), :created_at (u/new-sql-timestamp))
+    (simple-insert! Session, :id session-id, :user_id (user->id :trashbird), :created_at (u/new-sql-timestamp))
     (auth-enforced-handler (request-with-session-id session-id))))
 
 
diff --git a/test/metabase/models/pulse_test.clj b/test/metabase/models/pulse_test.clj
index 88cfe49bbc9ace4cd07248f66202fe12b207be1b..3985251a1c92a75c899afea721965381d00a72e7 100644
--- a/test/metabase/models/pulse_test.clj
+++ b/test/metabase/models/pulse_test.clj
@@ -20,7 +20,7 @@
 ;; create a channel then select its details
 (defn- create-pulse-then-select!
   [name creator cards channels]
-  (let [{:keys [cards channels] :as pulse} (create-pulse name creator cards channels)]
+  (let [{:keys [cards channels] :as pulse} (create-pulse! name creator cards channels)]
     (-> pulse
         (dissoc :id :creator :public_perms :created_at :updated_at)
         (assoc :cards (mapv #(dissoc % :id) cards))
@@ -116,7 +116,7 @@
         (dissoc :id :pulse_id :created_at :updated_at)
         (m/dissoc-in [:details :emails]))))
 
-;; create-pulse
+;; create-pulse!
 ;; simple example with a single card
 (expect
   {:creator_id (user->id :rasta)
diff --git a/test/metabase/models/session_test.clj b/test/metabase/models/session_test.clj
index f576aa707bcc5a8f9156d129c704aced89b13a39..dff89ad8077dcc3b9ba14156f073949fa468b612 100644
--- a/test/metabase/models/session_test.clj
+++ b/test/metabase/models/session_test.clj
@@ -1,12 +1,13 @@
 (ns metabase.models.session-test
   (:require [expectations :refer :all]
-            [metabase.db :as db]
+            metabase.db
             (metabase.models [session :refer :all]
                              [user :refer [User]])
             [metabase.test.util :refer :all]
             [metabase.test.data.users :refer :all]
             [metabase.util :as u]))
 
+(resolve-private-fns metabase.db simple-insert-many!)
 ;; first-session-for-user
 (expect
   "the-greatest-day-ever"
@@ -14,7 +15,7 @@
                                   :last_name  (random-name)
                                   :email      (str (random-name) "@metabase.com")
                                   :password   "nada"}]
-    (db/simple-insert-many! Session
+    (simple-insert-many! Session
       [{:id         "the-greatest-day-ever"
         :user_id    user-id
         :created_at (u/->Timestamp "1980-10-19T05:05:05.000Z")}
diff --git a/test/metabase/query_processor_test.clj b/test/metabase/query_processor_test.clj
index 5a344e08629df1b03944f98c7d366409038d1d20..2c540dc209c5c41ac9fe2811fcb3c095a93a1819 100644
--- a/test/metabase/query_processor_test.clj
+++ b/test/metabase/query_processor_test.clj
@@ -254,8 +254,8 @@
 (defn- breakout-col [column]
   (assoc column :source :breakout))
 
-(defn boolean-native-form
-  "Convert :native_form attribute to a boolean to make test results comparisons easier"
+(defn- booleanize-native-form
+  "Convert `:native_form` attribute to a boolean to make test results comparisons easier."
   [m]
   (update-in m [:data :native_form] boolean))
 
@@ -327,7 +327,7 @@
      :native_form true}
     (->> (run-query venues
            (ql/aggregation (ql/count)))
-         boolean-native-form
+         booleanize-native-form
          (format-rows-by [int])))
 
 
@@ -339,7 +339,7 @@
      :native_form true}
     (->> (run-query venues
            (ql/aggregation (ql/sum $price)))
-         boolean-native-form
+         booleanize-native-form
          (format-rows-by [int])))
 
 
@@ -351,7 +351,7 @@
      :native_form true}
     (->> (run-query venues
            (ql/aggregation (ql/avg $latitude)))
-         boolean-native-form
+         booleanize-native-form
          (format-rows-by [(partial u/round-to-decimals 4)])))
 
 
@@ -363,7 +363,7 @@
      :native_form true}
     (->> (run-query checkins
            (ql/aggregation (ql/distinct $user_id)))
-         boolean-native-form
+         booleanize-native-form
          (format-rows-by [int])))
 
 
@@ -386,7 +386,7 @@
     (->> (run-query venues
            (ql/limit 10)
            (ql/order-by (ql/asc $id)))
-         boolean-native-form
+         booleanize-native-form
          formatted-venues-rows))
 
 
@@ -532,7 +532,7 @@
   (->> (run-query checkins
                   (ql/aggregation (ql/count))
                   (ql/filter (ql/between $date "2015-04-01" "2015-05-01")))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int])))
 
 ;;; FILTER -- "OR", "<=", "="
@@ -592,7 +592,7 @@
                   (ql/fields $name $id)
                   (ql/limit 10)
                   (ql/order-by (ql/asc $id)))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [str int])))
 
 
@@ -609,7 +609,7 @@
                   (ql/aggregation (ql/count))
                   (ql/breakout $user_id)
                   (ql/order-by (ql/asc $user_id)))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 ;;; BREAKOUT w/o AGGREGATION
@@ -622,7 +622,7 @@
   (->> (run-query checkins
                   (ql/breakout $user_id)
                   (ql/limit 10))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int])))
 
 
@@ -641,7 +641,7 @@
                   (ql/aggregation (ql/count))
                   (ql/breakout $user_id $venue_id)
                   (ql/limit 10))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int int])))
 
 ;;; "BREAKOUT" - MULTIPLE COLUMNS W/ EXPLICIT "ORDER_BY"
@@ -660,7 +660,7 @@
                   (ql/breakout $user_id $venue_id)
                   (ql/order-by (ql/desc $user_id))
                   (ql/limit 10))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int int])))
 
 
@@ -699,7 +699,7 @@
      :native_form true}
   (->> (run-query users
          (ql/aggregation (ql/cum-sum $id)))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int])))
 
 
@@ -712,7 +712,7 @@
     (->> (run-query users
            (ql/aggregation (ql/cum-sum $id))
            (ql/breakout $id))
-         boolean-native-form
+         booleanize-native-form
          (format-rows-by [int])))
 
 
@@ -741,7 +741,7 @@
   (->> (run-query users
          (ql/aggregation (ql/cum-sum $id))
          (ql/breakout $name))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [str int])))
 
 
@@ -759,7 +759,7 @@
   (->> (run-query venues
          (ql/aggregation (ql/cum-sum $id))
          (ql/breakout $price))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 
@@ -778,7 +778,7 @@
      :native_form true}
   (->> (run-query users
                   (ql/aggregation (ql/cum-count)))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int])))
 
 ;;; Cumulative count w/ a different breakout field
@@ -806,7 +806,7 @@
   (->> (run-query users
          (ql/aggregation (ql/cum-count))
          (ql/breakout $name))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [str int])))
 
 
@@ -824,7 +824,7 @@
   (->> (run-query venues
          (ql/aggregation (ql/cum-count))
          (ql/breakout $price))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 
@@ -837,7 +837,7 @@
    :native_form true}
   (-> (run-query venues
         (ql/aggregation (ql/stddev $latitude)))
-      boolean-native-form
+      booleanize-native-form
       (update-in [:data :rows] (fn [[[v]]]
                                  [[(u/round-to-decimals 1 v)]]))))
 
@@ -867,7 +867,7 @@
          (ql/aggregation (ql/count))
          (ql/breakout $price)
          (ql/order-by (ql/asc (ql/aggregate-field 0))))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 
@@ -886,7 +886,7 @@
          (ql/aggregation (ql/sum $id))
          (ql/breakout $price)
          (ql/order-by (ql/desc (ql/aggregate-field 0))))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 
@@ -905,7 +905,7 @@
          (ql/aggregation (ql/distinct $id))
          (ql/breakout $price)
          (ql/order-by (ql/asc (ql/aggregate-field 0))))
-       boolean-native-form
+       booleanize-native-form
        (format-rows-by [int int])))
 
 
@@ -924,7 +924,7 @@
          (ql/aggregation (ql/avg $category_id))
          (ql/breakout $price)
          (ql/order-by (ql/asc (ql/aggregate-field 0))))
-       boolean-native-form
+       booleanize-native-form
        :data (format-rows-by [int int])))
 
 ;;; ### order_by aggregate ["stddev" field-id]
@@ -944,7 +944,7 @@
          (ql/aggregation (ql/stddev $category_id))
          (ql/breakout $price)
          (ql/order-by (ql/desc (ql/aggregate-field 0))))
-       boolean-native-form
+       booleanize-native-form
        :data (format-rows-by [int (comp int math/round)])))
 
 
@@ -996,7 +996,7 @@
   ;; Filter out the timestamps from the results since they're hard to test :/
   (-> (run-query users
         (ql/order-by (ql/asc $id)))
-      boolean-native-form
+      booleanize-native-form
       (update-in [:data :rows] (partial mapv (fn [[id name last-login]]
                                                [(int id) name])))))
 
@@ -1276,7 +1276,7 @@
          (run-query tips
            (ql/aggregation (ql/count))
            (ql/breakout $tips.source.service)))
-       boolean-native-form
+       booleanize-native-form
        :data (#(dissoc % :cols)) (format-rows-by [str int])))
 
 ;;; Nested Field in FIELDS