diff --git a/src/metabase/driver.clj b/src/metabase/driver.clj
index 96b55cdf6be7fe043724cee6416b0ed7fcce18ca..b2a9010c1287a1d18f838a7f4fbcbc268c9f6363 100644
--- a/src/metabase/driver.clj
+++ b/src/metabase/driver.clj
@@ -1,5 +1,5 @@
 (ns metabase.driver
-  (:require clojure.java.classpath
+  (:require [clojure.java.classpath :as classpath]
             [clojure.string :as s]
             [clojure.tools.logging :as log]
             [clojure.tools.namespace.find :as ns-find]
@@ -13,26 +13,269 @@
 
 (declare -dataset-query query-fail query-complete save-query-execution)
 
+;;; ## INTERFACE + CONSTANTS
+
+(def ^:const max-sync-lazy-seq-results
+  "The maximum number of values we should return when using `field-values-lazy-seq`.
+   This many is probably fine for inferring special types and what-not; we don't want
+   to scan millions of values at any rate."
+  10000)
+
+(def ^:const connection-error-messages
+  "Generic error messages that drivers should return in their implementation of `humanize-connection-error-message`."
+  {:cannot-connect-check-host-and-port "Hmm, we couldn't connect to the database. Make sure your host and port settings are correct."
+   :database-name-incorrect            "Looks like the database name is incorrect."
+   :invalid-hostname                   "It looks like your host is invalid. Please double-check it and try again."
+   :password-incorrect                 "Looks like your password is incorrect."
+   :password-required                  "Looks like you forgot to enter your password."
+   :username-incorrect                 "Looks like your username is incorrect."
+   :username-or-password-incorrect     "Looks like the username or password is incorrect."})
+
+(def ^:private ^:const feature->required-fns
+  "Map of optional driver features (as keywords) to a set of functions drivers that support that feature must define."
+  {:foreign-keys                       #{:table-fks}
+   :nested-fields                      #{:active-nested-field-name->type}
+   :set-timezone                       nil
+   :standard-deviation-aggregations    nil
+   :unix-timestamp-special-type-fields nil})
+
+(def ^:private ^:const optional-features
+  (set (keys feature->required-fns)))
+
+(def ^:private ^:const required-fns
+  #{:can-connect?
+    :active-table-names
+    :active-column-names->type
+    :table-pks
+    :field-values-lazy-seq
+    :process-query})
+
+(def ^:private ^:const optional-fns
+  #{:humanize-connection-error-message
+    :sync-in-context
+    :process-query-in-context
+    :table-rows-seq
+    :field-avg-length
+    :field-percent-urls
+    :driver-specific-sync-field!})
+
+(defn verify-driver
+  "Verify that a Metabase DB driver contains the expected properties and that they are the correct type."
+  [{:keys [driver-name details-fields features], :as driver}]
+  ;; Check :driver-name is a string
+  (assert driver-name
+    "Missing property :driver-name.")
+  (assert (string? driver-name)
+    ":driver-name must be a string.")
+
+  ;; Check the :details-fields
+  (assert details-fields
+    "Driver is missing property :details-fields.")
+  (assert (vector? details-fields)
+    ":details-fields should be a vector.")
+  (doseq [f details-fields]
+    (assert (map? f)
+      (format "Details fields must be maps: %s" f))
+    (assert (:name f)
+      (format "Details field %s is missing a :name property." f))
+    (assert (:display-name f)
+      (format "Details field %s is missing a :display-name property." f))
+    (when (:type f)
+      (assert (contains? #{:string :integer :password :boolean} (:type f))
+        (format "Invalid type %s in details field %s." (:type f) f)))
+    (when (:default f)
+      (assert (not (:placeholder f))
+        (format "Fields should not define both :default and :placeholder: %s" f))
+      (assert (not (:required f))
+        (format "Fields that define a :default cannot be :required: %s" f))))
+
+  ;; Check that all required functions are defined
+  (doseq [f required-fns]
+    (assert (f driver)
+      (format "Missing fn: %s" f))
+    (assert (fn? (f driver))
+      (format "Not a fn: %s" (f driver))))
+
+  ;; Check that all features declared are valid
+  (when features
+    (assert (and (set? features)
+                 (every? keyword? features))
+      ":features must be a set of keywords.")
+    (doseq [feature features]
+      (assert (contains? optional-features feature)
+        (format "Not a valid feature: %s" feature))
+      (doseq [f (feature->required-fns feature)]
+        (assert (f driver)
+          (format "Drivers that support feature %s must have fn %s." feature f))
+        (assert (fn? (f driver))
+          (format "Not a fn: %s" f)))))
+
+  ;; Check that the optional fns, if included, are actually fns
+  (doseq [f optional-fns]
+    (when (f driver)
+      (assert (fn? (f driver))
+        (format "Not a fn: %s" f)))))
+
+(defmacro defdriver
+  "Define and validate a new Metabase DB driver.
+
+   All drivers must include the following keys:
+
+#### PROPERTIES
+
+*  `:driver-name`
+
+    A human-readable string naming the DB this driver works with, e.g. `\"PostgreSQL\"`.
+
+*  `:details-fields`
+
+    A vector of maps that contain information about connection properties that should
+    be exposed to the user for databases that will use this driver. This information is used to build the UI for editing
+    a `Database` `details` map, and for validating it on the Backend. It should include things like `host`,
+    `port`, and other driver-specific parameters. Each field information map should have the following properties:
+
+    *  `:name`
+
+        The key that should be used to store this property in the `details` map.
+
+    *  `:display-name`
+
+        Human-readable name that should be displayed to the User in UI for editing this field.
+
+    *  `:type` *(OPTIONAL)*
+
+       `:string`, `:integer`, `:boolean`, or `:password`. Defaults to `:string`.
+
+    *  `:default` *(OPTIONAL)*
+
+        A default value for this field if the user hasn't set an explicit value. This is shown in the UI as a placeholder.
+
+    *  `:placeholder` *(OPTIONAL)*
+
+       Placeholder value to show in the UI if user hasn't set an explicit value. Similar to `:default`, but this value is
+       *not* saved to `:details` if no explicit value is set. Since `:default` values are also shown as placeholders, you
+       cannot specify both `:default` and `:placeholder`.
+
+    *  `:required` *(OPTIONAL)*
+
+       Is this property required? Defaults to `false`.
+
+*  `:features` *(OPTIONAL)*
+
+    A set of keyword names of optional features supported by this driver, such as `:foreign-keys`.
+
+#### FUNCTIONS
+
+*  `(can-connect? [details-map])`
+
+   Check whether we can connect to a `Database` with DETAILS-MAP and perform a simple query. For example, a SQL database might
+   try running a query like `SELECT 1;`. This function should return `true` or `false`.
+
+*  `(active-table-names [database])`
+
+   Return a set of string names of tables, collections, or equivalent that currently exist in DATABASE.
+
+*  `(active-column-names->type [table])`
+
+   Return a map of string names of active columns (or equivalent) -> `Field` `base_type` for TABLE (or equivalent).
+
+*  `(table-pks [table])`
+
+   Return a set of string names of active Fields that are primary keys for TABLE (or equivalent).
+
+*  `(field-values-lazy-seq [field])`
+
+   Return a lazy sequence of all values of FIELD.
+   This is used to implement `mark-json-field!`, and fallback implentations of `mark-no-preview-display-field!` and `mark-url-field!`
+   if drivers *don't* implement `field-avg-length` and `field-percent-urls`, respectively.
+
+*  `(process-query [query])`
+
+   Process a native or structured QUERY. This function is called by `metabase.driver/process-query` after performing various driver-unspecific
+   steps like Query Expansion and other preprocessing.
+
+*  `(table-fks [table])` *(REQUIRED FOR DRIVERS THAT SUPPORT `:foreign-keys`)*
+
+   Return a set of maps containing info about FK columns for TABLE.
+   Each map should contain the following keys:
+
+     *  `fk-column-name`
+     *  `dest-table-name`
+     *  `dest-column-name`
+
+*  `(active-nested-field-name->type [field])` *(REQUIRED FOR DRIVERS THAT SUPPORT `:nested-fields`)*
+
+   Return a map of string names of active child `Fields` of FIELD -> `Field.base_type`.
+
+*  `(humanize-connection-error-message [message])` *(OPTIONAL)*
+
+   Return a humanized (user-facing) version of an connection error message string.
+   Generic error messages are provided in the constant `connection-error-messages`; return one of these whenever possible.
+
+*  `(sync-in-context [database f])` *(OPTIONAL)*
+
+   Drivers may provide this function if they need to do special setup before a sync operation such as `sync-database!`. The sync
+   operation itself is encapsulated as the lambda F, which must be called with no arguments.
+
+       (defn sync-in-context [database f]
+         (with-jdbc-metadata [_ database]
+           (f)))
+
+*  `(process-query-in-context [f])` *(OPTIONAL)*
+
+   Similar to `sync-in-context`, but for running queries rather than syncing. This should be used to do things like open DB connections
+   that need to remain open for the duration of post-processing. This function follows a middleware pattern and is injected into the QP
+   middleware stack immediately after the Query Expander; in other words, it will receive the expanded query.
+   See the Mongo and H2 drivers for examples of how this is intended to be used.
+
+*  `(table-rows-seq [database table-name])` *(OPTIONAL)*
+
+   Return a sequence of all the rows in a table with a given TABLE-NAME.
+   Currently, this is only used for iterating over the values in a `_metabase_metadata` table. As such, the results are not expected to be returned lazily.
+
+*  `(field-avg-length [field])` *(OPTIONAL)*
+
+   If possible, provide an efficent DB-level function to calculate the average length of non-nil values of textual FIELD, which is used to determine whether a `Field`
+   should be marked as a `:category`. If this function is not provided, a fallback implementation that iterates over results in Clojure-land is used instead.
+
+*  `(field-percent-urls [field])` *(OPTIONAL)*
+
+   If possible, provide an efficent DB-level function to calculate what percentage of non-nil values of textual FIELD are valid URLs, which is used to determine
+   whether a `Field` should be marked as a `:url`. If this function is not provided, a fallback implementation that iterates over results in Clojure-land is used instead.
+
+*  `(driver-specific-sync-field! [field])` *(OPTIONAL)*
+
+   This is a chance for drivers to do custom `Field` syncing specific to their database.
+   For example, the Postgres driver can mark Postgres JSON fields as `special_type = json`.
+   As with the other Field syncing functions in `metabase.driver.sync`, this method should return the modified FIELD, if any, or `nil`."
+  [driver-name driver-map]
+  `(def ~(vary-meta driver-name assoc :metabase.driver/driver (keyword driver-name))
+     (let [m# ~driver-map]
+       (verify-driver m#)
+       m#)))
+
+
 ;;; ## CONFIG
 
 (defsetting report-timezone "Connection timezone to use when executing queries. Defaults to system timezone.")
 
-;; ## Constants
+(defn- -available-drivers []
+  (->> (for [namespace (->> (ns-find/find-namespaces (classpath/classpath))
+                            (filter (fn [ns-symb]
+                                      (re-matches #"^metabase\.driver\.[a-z0-9_]+$" (name ns-symb)))))]
+         (do (require namespace)
+             (->> (ns-publics namespace)
+                  (map (fn [[symb varr]]
+                         (when (::driver (meta varr))
+                           {(keyword symb) (select-keys @varr [:details-fields
+                                                               :driver-name
+                                                               :features])})))
+                  (into {}))))
+       (into {})))
 
 (def available-drivers
   "Delay to a map of info about available drivers."
-  (delay (->> (for [namespace (->> (ns-find/find-namespaces (clojure.java.classpath/classpath))
-                                   (filter (fn [ns-symb]
-                                             (re-matches #"^metabase\.driver\.[a-z0-9_]+$" (name ns-symb)))))]
-                (do (require namespace)
-                    (->> (ns-publics namespace)
-                         (map (fn [[symb varr]]
-                                (when (::driver (meta varr))
-                                  {(keyword symb) (select-keys @varr [:details-fields
-                                                                      :driver-name
-                                                                      :features])})))
-                         (into {}))))
-              (into {}))))
+  (delay (-available-drivers)))
 
 (defn is-engine?
   "Is ENGINE a valid driver name?"
diff --git a/src/metabase/driver/generic_sql.clj b/src/metabase/driver/generic_sql.clj
index ca77f59b92f399535175f890209315883545ac53..4cea8c8a18f9661f5ddc8aeec1eecb28f83918c1 100644
--- a/src/metabase/driver/generic_sql.clj
+++ b/src/metabase/driver/generic_sql.clj
@@ -3,9 +3,7 @@
             [clojure.tools.logging :as log]
             [korma.core :as k]
             [korma.sql.utils :as utils]
-            [metabase.driver :as driver]
-            (metabase.driver [interface :refer [max-sync-lazy-seq-results defdriver]]
-                             [sync :as driver-sync])
+            [metabase.driver :refer [max-sync-lazy-seq-results defdriver]]
             (metabase.driver.generic-sql [query-processor :as qp]
                                          [util :refer :all])
             [metabase.models.field :as field]
diff --git a/src/metabase/driver/h2.clj b/src/metabase/driver/h2.clj
index 7219f041807ae613d02e3ea1c7eae4fb54790186..9a0f0c628055c8c3c85cd6fce0aaa495e064ff36 100644
--- a/src/metabase/driver/h2.clj
+++ b/src/metabase/driver/h2.clj
@@ -3,8 +3,8 @@
             [korma.db :as kdb]
             [korma.sql.utils :as utils]
             [metabase.db :as db]
-            (metabase.driver [generic-sql :refer [sql-driver]]
-                             [interface :as i, :refer [defdriver]])
+            [metabase.driver :as driver, :refer [defdriver]]
+            [metabase.driver.generic-sql :refer [sql-driver]]
             [metabase.driver.generic-sql.util :refer [funcs]]
             [metabase.models.database :refer [Database]]))
 
@@ -183,13 +183,13 @@
 (defn- humanize-connection-error-message [message]
   (condp re-matches message
     #"^A file path that is implicitly relative to the current working directory is not allowed in the database URL .*$"
-    (i/connection-error-messages :cannot-connect-check-host-and-port)
+    (driver/connection-error-messages :cannot-connect-check-host-and-port)
 
     #"^Database .* not found .*$"
-    (i/connection-error-messages :cannot-connect-check-host-and-port)
+    (driver/connection-error-messages :cannot-connect-check-host-and-port)
 
     #"^Wrong user name or password .*$"
-    (i/connection-error-messages :username-or-password-incorrect)
+    (driver/connection-error-messages :username-or-password-incorrect)
 
     #".*" ; default
     message))
diff --git a/src/metabase/driver/interface.clj b/src/metabase/driver/interface.clj
deleted file mode 100644
index 8baea6b53f4f620fcfefedb8a9a70dc5a53124be..0000000000000000000000000000000000000000
--- a/src/metabase/driver/interface.clj
+++ /dev/null
@@ -1,240 +0,0 @@
-(ns metabase.driver.interface)
-
-(def ^:const max-sync-lazy-seq-results
-  "The maximum number of values we should return when using `field-values-lazy-seq`.
-   This many is probably fine for inferring special types and what-not; we don't want
-   to scan millions of values at any rate."
-  10000)
-
-(def ^:const connection-error-messages
-  "Generic error messages that drivers should return in their implementation of `humanize-connection-error-message`."
-  {:cannot-connect-check-host-and-port "Hmm, we couldn't connect to the database. Make sure your host and port settings are correct."
-   :database-name-incorrect            "Looks like the database name is incorrect."
-   :invalid-hostname                   "It looks like your host is invalid. Please double-check it and try again."
-   :password-incorrect                 "Looks like your password is incorrect."
-   :password-required                  "Looks like you forgot to enter your password."
-   :username-incorrect                 "Looks like your username is incorrect."
-   :username-or-password-incorrect     "Looks like the username or password is incorrect."})
-
-(def ^:private ^:const feature->required-fns
-  "Map of optional driver features (as keywords) to a set of functions drivers that support that feature must define."
-  {:foreign-keys                       #{:table-fks}
-   :nested-fields                      #{:active-nested-field-name->type}
-   :set-timezone                       nil
-   :standard-deviation-aggregations    nil
-   :unix-timestamp-special-type-fields nil})
-
-(def ^:private ^:const optional-features
-  (set (keys feature->required-fns)))
-
-(def ^:private ^:const required-fns
-  #{:can-connect?
-    :active-table-names
-    :active-column-names->type
-    :table-pks
-    :field-values-lazy-seq
-    :process-query})
-
-(def ^:private ^:const optional-fns
-  #{:humanize-connection-error-message
-    :sync-in-context
-    :process-query-in-context
-    :table-rows-seq
-    :field-avg-length
-    :field-percent-urls
-    :driver-specific-sync-field!})
-
-(defn verify-driver
-  "Verify that a Metabase DB driver contains the expected properties and that they are the correct type."
-  [{:keys [driver-name details-fields features], :as driver}]
-  ;; Check :driver-name is a string
-  (assert driver-name
-    "Missing property :driver-name.")
-  (assert (string? driver-name)
-    ":driver-name must be a string.")
-
-  ;; Check the :details-fields
-  (assert details-fields
-    "Driver is missing property :details-fields.")
-  (assert (vector? details-fields)
-    ":details-fields should be a vector.")
-  (doseq [f details-fields]
-    (assert (map? f)
-      (format "Details fields must be maps: %s" f))
-    (assert (:name f)
-      (format "Details field %s is missing a :name property." f))
-    (assert (:display-name f)
-      (format "Details field %s is missing a :display-name property." f))
-    (when (:type f)
-      (assert (contains? #{:string :integer :password :boolean} (:type f))
-        (format "Invalid type %s in details field %s." (:type f) f)))
-    (when (:default f)
-      (assert (not (:placeholder f))
-        (format "Fields should not define both :default and :placeholder: %s" f))
-      (assert (not (:required f))
-        (format "Fields that define a :default cannot be :required: %s" f))))
-
-  ;; Check that all required functions are defined
-  (doseq [f required-fns]
-    (assert (f driver)
-      (format "Missing fn: %s" f))
-    (assert (fn? (f driver))
-      (format "Not a fn: %s" (f driver))))
-
-  ;; Check that all features declared are valid
-  (when features
-    (assert (and (set? features)
-                 (every? keyword? features))
-      ":features must be a set of keywords.")
-    (doseq [feature features]
-      (assert (contains? optional-features feature)
-        (format "Not a valid feature: %s" feature))
-      (doseq [f (feature->required-fns feature)]
-        (assert (f driver)
-          (format "Drivers that support feature %s must have fn %s." feature f))
-        (assert (fn? (f driver))
-          (format "Not a fn: %s" f)))))
-
-  ;; Check that the optional fns, if included, are actually fns
-  (doseq [f optional-fns]
-    (when (f driver)
-      (assert (fn? (f driver))
-        (format "Not a fn: %s" f)))))
-
-(defmacro defdriver
-  "Define and validate a new Metabase DB driver.
-
-   All drivers must include the following keys:
-
-#### PROPERTIES
-
-*  `:driver-name`
-
-    A human-readable string naming the DB this driver works with, e.g. `\"PostgreSQL\"`.
-
-*  `:details-fields`
-
-    A vector of maps that contain information about connection properties that should
-    be exposed to the user for databases that will use this driver. This information is used to build the UI for editing
-    a `Database` `details` map, and for validating it on the Backend. It should include things like `host`,
-    `port`, and other driver-specific parameters. Each field information map should have the following properties:
-
-    *  `:name`
-
-        The key that should be used to store this property in the `details` map.
-
-    *  `:display-name`
-
-        Human-readable name that should be displayed to the User in UI for editing this field.
-
-    *  `:type` *(OPTIONAL)*
-
-       `:string`, `:integer`, `:boolean`, or `:password`. Defaults to `:string`.
-
-    *  `:default` *(OPTIONAL)*
-
-        A default value for this field if the user hasn't set an explicit value. This is shown in the UI as a placeholder.
-
-    *  `:placeholder` *(OPTIONAL)*
-
-       Placeholder value to show in the UI if user hasn't set an explicit value. Similar to `:default`, but this value is
-       *not* saved to `:details` if no explicit value is set. Since `:default` values are also shown as placeholders, you
-       cannot specify both `:default` and `:placeholder`.
-
-    *  `:required` *(OPTIONAL)*
-
-       Is this property required? Defaults to `false`.
-
-*  `:features` *(OPTIONAL)*
-
-    A set of keyword names of optional features supported by this driver, such as `:foreign-keys`.
-
-#### FUNCTIONS
-
-*  `(can-connect? [details-map])`
-
-   Check whether we can connect to a `Database` with DETAILS-MAP and perform a simple query. For example, a SQL database might
-   try running a query like `SELECT 1;`. This function should return `true` or `false`.
-
-*  `(active-table-names [database])`
-
-   Return a set of string names of tables, collections, or equivalent that currently exist in DATABASE.
-
-*  `(active-column-names->type [table])`
-
-   Return a map of string names of active columns (or equivalent) -> `Field` `base_type` for TABLE (or equivalent).
-
-*  `(table-pks [table])`
-
-   Return a set of string names of active Fields that are primary keys for TABLE (or equivalent).
-
-*  `(field-values-lazy-seq [field])`
-
-   Return a lazy sequence of all values of FIELD.
-   This is used to implement `mark-json-field!`, and fallback implentations of `mark-no-preview-display-field!` and `mark-url-field!`
-   if drivers *don't* implement `field-avg-length` and `field-percent-urls`, respectively.
-
-*  `(process-query [query])`
-
-   Process a native or structured QUERY. This function is called by `metabase.driver/process-query` after performing various driver-unspecific
-   steps like Query Expansion and other preprocessing.
-
-*  `(table-fks [table])` *(REQUIRED FOR DRIVERS THAT SUPPORT `:foreign-keys`)*
-
-   Return a set of maps containing info about FK columns for TABLE.
-   Each map should contain the following keys:
-
-     *  `fk-column-name`
-     *  `dest-table-name`
-     *  `dest-column-name`
-
-*  `(active-nested-field-name->type [field])` *(REQUIRED FOR DRIVERS THAT SUPPORT `:nested-fields`)*
-
-   Return a map of string names of active child `Fields` of FIELD -> `Field.base_type`.
-
-*  `(humanize-connection-error-message [message])` *(OPTIONAL)*
-
-   Return a humanized (user-facing) version of an connection error message string.
-   Generic error messages are provided in the constant `connection-error-messages`; return one of these whenever possible.
-
-*  `(sync-in-context [database f])` *(OPTIONAL)*
-
-   Drivers may provide this function if they need to do special setup before a sync operation such as `sync-database!`. The sync
-   operation itself is encapsulated as the lambda F, which must be called with no arguments.
-
-       (defn sync-in-context [database f]
-         (with-jdbc-metadata [_ database]
-           (f)))
-
-*  `(process-query-in-context [f])` *(OPTIONAL)*
-
-   Similar to `sync-in-context`, but for running queries rather than syncing. This should be used to do things like open DB connections
-   that need to remain open for the duration of post-processing. This function follows a middleware pattern and is injected into the QP
-   middleware stack immediately after the Query Expander; in other words, it will receive the expanded query.
-   See the Mongo and H2 drivers for examples of how this is intended to be used.
-
-*  `(table-rows-seq [database table-name])` *(OPTIONAL)*
-
-   Return a sequence of all the rows in a table with a given TABLE-NAME.
-   Currently, this is only used for iterating over the values in a `_metabase_metadata` table. As such, the results are not expected to be returned lazily.
-
-*  `(field-avg-length [field])` *(OPTIONAL)*
-
-   If possible, provide an efficent DB-level function to calculate the average length of non-nil values of textual FIELD, which is used to determine whether a `Field`
-   should be marked as a `:category`. If this function is not provided, a fallback implementation that iterates over results in Clojure-land is used instead.
-
-*  `(field-percent-urls [field])` *(OPTIONAL)*
-
-   If possible, provide an efficent DB-level function to calculate what percentage of non-nil values of textual FIELD are valid URLs, which is used to determine
-   whether a `Field` should be marked as a `:url`. If this function is not provided, a fallback implementation that iterates over results in Clojure-land is used instead.
-
-*  `(driver-specific-sync-field! [field])` *(OPTIONAL)*
-
-   This is a chance for drivers to do custom `Field` syncing specific to their database.
-   For example, the Postgres driver can mark Postgres JSON fields as `special_type = json`.
-   As with the other Field syncing functions in `metabase.driver.sync`, this method should return the modified FIELD, if any, or `nil`."
-  [driver-name driver-map]
-  `(def ~(vary-meta driver-name assoc :metabase.driver/driver (keyword driver-name))
-     (let [m# ~driver-map]
-       (verify-driver m#)
-       m#)))
diff --git a/src/metabase/driver/mongo.clj b/src/metabase/driver/mongo.clj
index 829090aa9ee1743e4f3eab8dba269245353e1845..dc077d8f56ae57cef9da4dd7e2643e415f3a7a72 100644
--- a/src/metabase/driver/mongo.clj
+++ b/src/metabase/driver/mongo.clj
@@ -11,8 +11,7 @@
                     [core :as mg]
                     [db :as mdb]
                     [query :as mq])
-            [metabase.driver :as driver]
-            [metabase.driver.interface :as i, :refer [defdriver]]
+            [metabase.driver :as driver, :refer [defdriver]]
             (metabase.driver.mongo [query-processor :as qp]
                                    [util :refer [*mongo-connection* with-mongo-connection values->base-type]])
             [metabase.util :as u]))
@@ -27,7 +26,7 @@
   [table]
   (with-mongo-connection [^com.mongodb.DB conn @(:db table)]
     (->> (mc/find-maps conn (:name table))
-         (take i/max-sync-lazy-seq-results)
+         (take driver/max-sync-lazy-seq-results)
          (map keys)
          (map set)
          (reduce set/union))))
@@ -53,13 +52,13 @@
 (defn- humanize-connection-error-message [message]
   (condp re-matches message
     #"^Timed out after \d+ ms while waiting for a server .*$"
-    (i/connection-error-messages :cannot-connect-check-host-and-port)
+    (driver/connection-error-messages :cannot-connect-check-host-and-port)
 
     #"^host and port should be specified in host:port format$"
-    (i/connection-error-messages :invalid-hostname)
+    (driver/connection-error-messages :invalid-hostname)
 
     #"^Password can not be null when the authentication mechanism is unspecified$"
-    (i/connection-error-messages :password-required)
+    (driver/connection-error-messages :password-required)
 
     #".*"                               ; default
     message))
@@ -109,7 +108,7 @@
   ;; Build a map of nested-field-key -> type -> count
   ;; TODO - using an atom isn't the *fastest* thing in the world (but is the easiest); consider alternate implementation
   (let [field->type->count (atom {})]
-    (doseq [val (take i/max-sync-lazy-seq-results (field-values-lazy-seq field))]
+    (doseq [val (take driver/max-sync-lazy-seq-results (field-values-lazy-seq field))]
       (when (map? val)
         (doseq [[k v] val]
           (swap! field->type->count update-in [k (type v)] #(if % (inc %) 1)))))
diff --git a/src/metabase/driver/mysql.clj b/src/metabase/driver/mysql.clj
index fadc19bc5fd837b4eb5cfc97990eec7e4a99b1e5..92bec2a2fc7888c11e1059ac17996c83ee6e40c8 100644
--- a/src/metabase/driver/mysql.clj
+++ b/src/metabase/driver/mysql.clj
@@ -6,8 +6,8 @@
                    mysql)
             (korma.sql [engine :refer [sql-func]]
                        [utils :as utils])
-            (metabase.driver [generic-sql :refer [sql-driver]]
-                             [interface :as i, :refer [defdriver]])
+            [metabase.driver :as driver, :refer [defdriver]]
+            [metabase.driver.generic-sql :refer [sql-driver]]
             [metabase.driver.generic-sql.util :refer [funcs]]))
 
 ;;; # Korma 0.4.2 Bug Workaround
@@ -129,16 +129,16 @@
 (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.$"
-        (i/connection-error-messages :cannot-connect-check-host-and-port)
+        (driver/connection-error-messages :cannot-connect-check-host-and-port)
 
         #"^Unknown database .*$"
-        (i/connection-error-messages :database-name-incorrect)
+        (driver/connection-error-messages :database-name-incorrect)
 
         #"Access denied for user.*$"
-        (i/connection-error-messages :username-or-password-incorrect)
+        (driver/connection-error-messages :username-or-password-incorrect)
 
         #"Must specify port after ':' in connection string"
-        (i/connection-error-messages :invalid-hostname)
+        (driver/connection-error-messages :invalid-hostname)
 
         #".*" ; default
         message))
diff --git a/src/metabase/driver/postgres.clj b/src/metabase/driver/postgres.clj
index 66660c8cbcd049f2c30c840a8ccd251393ae2182..f7296de27510db6a88931dfcf509c07d09d8cf48 100644
--- a/src/metabase/driver/postgres.clj
+++ b/src/metabase/driver/postgres.clj
@@ -9,8 +9,8 @@
             [swiss.arrows :refer :all]
             [metabase.db :refer [upd]]
             [metabase.models.field :refer [Field]]
-            (metabase.driver [generic-sql :refer [sql-driver]]
-                             [interface :as i, :refer [defdriver]])
+            [metabase.driver :as driver, :refer [defdriver]]
+            [metabase.driver.generic-sql :refer [sql-driver]]
             [metabase.driver.generic-sql.util :refer [with-jdbc-metadata]])
   ;; This is necessary for when NonValidatingFactory is passed in the sslfactory connection string argument,
   ;; e.x. when connecting to a Heroku Postgres database from outside of Heroku.
@@ -148,19 +148,19 @@
 (defn- humanize-connection-error-message [message]
   (condp re-matches message
     #"^FATAL: database \".*\" does not exist$"
-    (i/connection-error-messages :database-name-incorrect)
+    (driver/connection-error-messages :database-name-incorrect)
 
     #"^No suitable driver found for.*$"
-    (i/connection-error-messages :invalid-hostname)
+    (driver/connection-error-messages :invalid-hostname)
 
     #"^Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.$"
-    (i/connection-error-messages :cannot-connect-check-host-and-port)
+    (driver/connection-error-messages :cannot-connect-check-host-and-port)
 
     #"^FATAL: role \".*\" does not exist$"
-    (i/connection-error-messages :username-incorrect)
+    (driver/connection-error-messages :username-incorrect)
 
     #"^FATAL: password authentication failed for user.*$"
-    (i/connection-error-messages :password-incorrect)
+    (driver/connection-error-messages :password-incorrect)
 
     #"^FATAL: .*$" ; all other FATAL messages: strip off the 'FATAL' part, capitalize, and add a period
     (let [[_ message] (re-matches #"^FATAL: (.*$)" message)]
diff --git a/src/metabase/driver/query_processor/expand.clj b/src/metabase/driver/query_processor/expand.clj
index fb1e3260e9073ffbde22fe9960bada756a101ace..1ea9947becbba0a1a5602cc45922350e062ee670 100644
--- a/src/metabase/driver/query_processor/expand.clj
+++ b/src/metabase/driver/query_processor/expand.clj
@@ -9,7 +9,6 @@
             [korma.core :as k]
             [swiss.arrows :refer [-<>]]
             [metabase.db :refer [sel]]
-            [metabase.driver.interface :as driver]
             [metabase.driver.query-processor.interface :refer :all]
             [metabase.util :as u])
   (:import (clojure.lang Keyword)))
diff --git a/src/metabase/driver/sync.clj b/src/metabase/driver/sync.clj
index d0dbafe4b96865d56a60b39b9d517ee517be2d94..e2431503f47341ac9bf0fcffef261709cc127906 100644
--- a/src/metabase/driver/sync.clj
+++ b/src/metabase/driver/sync.clj
@@ -8,8 +8,8 @@
             [korma.core :as k]
             [medley.core :as m]
             [metabase.db :refer :all]
-            (metabase.driver [interface :refer [max-sync-lazy-seq-results]]
-                             [query-processor :as qp])
+            [metabase.driver :refer [max-sync-lazy-seq-results]]
+            [metabase.driver.query-processor :as qp]
             [metabase.driver.sync.queries :as queries]
             [metabase.events :as events]
             (metabase.models [common :as common]
diff --git a/test/metabase/driver/sync_test.clj b/test/metabase/driver/sync_test.clj
index 8307fa680798e9488e15406b4ba7f6cb74c1f78b..dca5fb13e9d9b0aadbd0a4ea0898d85d17399c4d 100644
--- a/test/metabase/driver/sync_test.clj
+++ b/test/metabase/driver/sync_test.clj
@@ -4,7 +4,6 @@
             [metabase.db :refer :all]
             [metabase.driver :as driver]
             (metabase.driver [h2 :as h2]
-                             [interface :as i]
                              [sync :as sync])
             [metabase.driver.generic-sql.util :refer [korma-entity]]
             (metabase.models [field :refer [Field]]