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

Merge pull request #4680 from metabase/driver-cleanup-3000

Use JDBC metadata fn to fetch MATERIALIZED VIEWS (credit: @lindsay-stevens)
parents 9580c50f 47178189
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,7 @@
[metabase.sync-database.analyze :as analyze]
[metabase.util :as u]
[metabase.util.honeysql-extensions :as hx])
(:import java.sql.DatabaseMetaData
(:import (java.sql DatabaseMetaData ResultSet)
java.util.Map
(clojure.lang Keyword PersistentVector)
com.mchange.v2.c3p0.ComboPooledDataSource
......@@ -327,7 +327,6 @@
;;; ## Database introspection methods used by sync process
;; TODO - clojure.java.jdbc now ships with a `metadata-query` function we could use here. See #2918
(defmacro with-metadata
"Execute BODY with `java.sql.DatabaseMetaData` for DATABASE."
[[binding _ database] & body]
......@@ -335,6 +334,12 @@
(let [~binding (.getMetaData conn#)]
~@body)))
(defn- get-tables
"Fetch a JDBC Metadata ResultSet of tables in the DB, optionally limited to ones belonging to a given schema."
^ResultSet [^DatabaseMetaData metadata, ^String schema-or-nil]
(jdbc/result-set-seq (.getTables metadata nil schema-or-nil "%" ; tablePattern "%" = match all tables
(into-array String ["TABLE", "VIEW", "FOREIGN TABLE", "MATERIALIZED VIEW"]))))
(defn fast-active-tables
"Default, fast implementation of `ISQLDriver/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.
......@@ -344,7 +349,7 @@
(let [all-schemas (set (map :table_schem (jdbc/result-set-seq (.getSchemas metadata))))
schemas (set/difference all-schemas (excluded-schemas driver))]
(set (for [schema schemas
table-name (mapv :table_name (jdbc/result-set-seq (.getTables metadata nil schema "%" (into-array String ["TABLE", "VIEW", "FOREIGN TABLE"]))))] ; tablePattern "%" = match all tables
table-name (mapv :table_name (get-tables metadata schema))]
{:name table-name
:schema schema}))))
......@@ -353,7 +358,7 @@
Fetch *all* Tables, then filter out ones whose schema is in `excluded-schemas` Clojure-side."
[driver, ^DatabaseMetaData metadata]
(set (for [table (filter #(not (contains? (excluded-schemas driver) (:table_schem %)))
(jdbc/result-set-seq (.getTables metadata nil nil "%" (into-array String ["TABLE", "VIEW", "FOREIGN TABLE"]))))] ; tablePattern "%" = match all tables
(get-tables metadata nil))]
{:name (:table_name table)
:schema (:table_schem table)})))
......
......@@ -180,23 +180,6 @@
(isa? base-type :type/IPAddress) (hx/cast :inet value)
:else value)))
(defn- materialized-views
"Fetch the Materialized Views for a Postgres DATABASE.
These are returned as a set of maps, the same format as `:tables` returned by `describe-database`."
[database]
(try (set (jdbc/query (sql/db->jdbc-connection-spec database)
["SELECT schemaname AS \"schema\", matviewname AS \"name\" FROM pg_matviews;"]))
(catch Throwable e
(log/error "Failed to fetch materialized views for this database:" (.getMessage e)))))
(defn- describe-database
"Custom implementation of `describe-database` for Postgres.
Postgres Materialized Views are not returned by normal JDBC methods: see [issue #2355](https://github.com/metabase/metabase/issues/2355); we have to manually fetch them.
This implementation combines the results from the generic SQL default implementation with materialized views fetched from `materialized-views`."
[driver database]
(update (sql/describe-database driver database) :tables (u/rpartial set/union (materialized-views database))))
(defn- string-length-fn [field-key]
(hsql/call :char_length (hx/cast :VARCHAR field-key)))
......@@ -221,7 +204,6 @@
driver/IDriver
(merge (sql/IDriverSQLDefaultsMixin)
{:date-interval (u/drop-first-arg date-interval)
:describe-database describe-database
:details-fields (constantly [{:name "host"
:display-name "Host"
:default "localhost"}
......
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