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

Fast implementation of `active-tables` for SQL DBs :scream_cat:

parent ab3ff556
No related branches found
No related tags found
No related merge requests found
(ns metabase.driver.generic-sql
(:require [clojure.core.memoize :as memoize]
[clojure.java.jdbc :as jdbc]
[clojure.set :as set]
[clojure.tools.logging :as log]
(korma [core :as k]
[db :as kdb])
......@@ -125,12 +126,12 @@
(let [~binding (.getMetaData conn#)]
~@body)))
(defn- active-tables
"Fast implementation of `IDriver/active-tables`.
Fetches list of schemas, then for each one not in `excluded-schemas`, fetch their Tables.
The old implementation fetched *all* Tables, then filtered out ones with `excluded-schemas` in Clojure;
this is as much as 15x faster for Databases with a lot of system tables like Oracle (4 seconds vs 60)."
(defn fast-active-tables
"Default, fast implementation of `IDriver/active-tables` best suited for DBs with lots of system tables (like Oracle).
Fetch list of schemas, then for each one not in `excluded-schemas`, fetch its Tables, and combine the results.
This is as much as 15x faster for Databases with lots of system tables than `post-filtered-active-tables` (4 seconds vs 60)."
[driver database]
(with-metadata [md driver database]
(let [all-schemas (set (map :table_schem (jdbc/result-set-seq (.getSchemas md))))
......@@ -140,6 +141,17 @@
{:name table-name
:schema schema})))))
(defn post-filtered-active-tables
"Alternative implementation of `IDriver/active-tables` best suited for DBs with little or no support for schemas.
Fetch *all* Tables, then filter out ones whose schema is in `excluded-schemas` Clojure-side."
[driver database]
(with-metadata [md driver database]
(set (for [table (filter #(not (contains? (excluded-schemas driver) (:table_schem %)))
(jdbc/result-set-seq (.getTables md nil nil nil (into-array String ["TABLE", "VIEW"]))))]
{:name (:table_name table)
:schema (:table_schem table)}))))
(defn- active-column-names->type [driver table]
(with-metadata [md driver @(:db table)]
(into {} (for [{:keys [column_name type_name]} (jdbc/result-set-seq (.getColumns md nil (:schema table) (:name table) nil))]
......@@ -253,7 +265,7 @@
'metabase.driver.generic-sql.query-processor)
(merge driver/IDriverDefaultsMixin
{:active-column-names->type active-column-names->type
:active-tables active-tables
:active-tables fast-active-tables
:can-connect? can-connect?
:features features
:field-avg-length field-avg-length
......
......@@ -198,7 +198,8 @@
(extend H2Driver
driver/IDriver
(merge (sql/IDriverSQLDefaultsMixin)
{:date-interval date-interval
{:active-tables sql/post-filtered-active-tables
:date-interval date-interval
:details-fields (constantly [{:name "db"
:display-name "Connection String"
:placeholder "file:/Users/camsaul/bird_sightings/toucans;AUTO_SERVER=TRUE"
......
......@@ -141,7 +141,8 @@
(extend MySQLDriver
driver/IDriver
(merge (sql/IDriverSQLDefaultsMixin)
{:date-interval date-interval
{:active-tables sql/post-filtered-active-tables
:date-interval date-interval
:details-fields (constantly [{:name "host"
:display-name "Host"
:default "localhost"}
......
......@@ -108,7 +108,8 @@
(extend SQLiteDriver
driver/IDriver
(merge (sql/IDriverSQLDefaultsMixin)
{:date-interval date-interval
{:active-tables sql/post-filtered-active-tables
:date-interval date-interval
:details-fields (constantly [{:name "db"
:display-name "Filename"
:placeholder "/home/camsaul/toucan_sightings.sqlite 😋"
......
......@@ -84,12 +84,12 @@
(validate-active-tables active-tables)
(mark-inactive-tables! database active-tables existing-table->id)
(create-new-tables! database active-tables existing-table->id))
(create-new-tables! database active-tables existing-table->id)
(fetch-and-sync-database-active-tables! driver database)
(fetch-and-sync-database-active-tables! driver database)
;; Ok, now if we had a _metabase_metadata table from earlier we can go ahead and sync from it
(sync-metabase-metadata-table! driver database active-tables))
;; Ok, now if we had a _metabase_metadata table from earlier we can go ahead and sync from it
(sync-metabase-metadata-table! driver database active-tables)))
(defn- -sync-database-with-tracking! [driver database]
(let [start-time (System/currentTimeMillis)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment