Skip to content
Snippets Groups Projects
Unverified Commit 8947f42a authored by dpsutton's avatar dpsutton Committed by GitHub
Browse files

tree view for datasets (#18704)

* tree view for datasets

* Update docstring
parent 81b9fb6f
No related branches found
No related tags found
No related merge requests found
......@@ -121,8 +121,9 @@
(db/select-ids Database))))
(defn- source-query-cards
"Fetch the Cards that can be used as source queries (e.g. presented as virtual tables)."
[& {:keys [additional-constraints xform], :or {xform identity}}]
"Fetch the Cards that can be used as source queries (e.g. presented as virtual tables). Since Cards can be either `dataset` or `card`, pass in the `question-type` of `:dataset` or `:card`"
[question-type & {:keys [additional-constraints xform], :or {xform identity}}]
{:pre [(#{:card :dataset} question-type)]}
(when-let [ids-of-dbs-that-support-source-queries (not-empty (ids-of-dbs-that-support-source-queries))]
(transduce
(comp (map (partial models/do-post-select Card))
......@@ -144,6 +145,7 @@
:where (into [:and
[:not= :result_metadata nil]
[:= :archived false]
[:= :dataset (= question-type :dataset)]
[:in :database_id ids-of-dbs-that-support-source-queries]
(collection/visible-collection-ids->honeysql-filter-clause
(collection/permissions-set->visible-collection-ids @api/*current-user-permissions-set*))]
......@@ -152,31 +154,32 @@
(defn- source-query-cards-exist?
"Truthy if a single Card that can be used as a source query exists."
[]
(seq (source-query-cards :xform (take 1))))
[question-type]
(seq (source-query-cards question-type :xform (take 1))))
(defn- cards-virtual-tables
"Return a sequence of 'virtual' Table metadata for eligible Cards.
(This takes the Cards from `source-query-cards` and returns them in a format suitable for consumption by the Query
Builder.)"
[& {:keys [include-fields?]}]
(for [card (source-query-cards)]
[question-type & {:keys [include-fields?]}]
(for [card (source-query-cards question-type)]
(table-api/card->virtual-table card :include-fields? include-fields?)))
(defn- saved-cards-virtual-db-metadata [& {:keys [include-tables? include-fields?]}]
(defn- saved-cards-virtual-db-metadata [question-type & {:keys [include-tables? include-fields?]}]
(when (public-settings/enable-nested-queries)
(cond-> {:name (trs "Saved Questions")
:id mbql.s/saved-questions-virtual-database-id
:features #{:basic-aggregations}
:is_saved_questions true}
include-tables? (assoc :tables (cards-virtual-tables :include-fields? include-fields?)))))
include-tables? (assoc :tables (cards-virtual-tables question-type
:include-fields? include-fields?)))))
;; "Virtual" tables for saved cards simulate the db->schema->table hierarchy by doing fake-db->collection->card
(defn- add-saved-questions-virtual-database [dbs & options]
(let [virtual-db-metadata (apply saved-cards-virtual-db-metadata options)]
(let [virtual-db-metadata (apply saved-cards-virtual-db-metadata :card options)]
;; only add the 'Saved Questions' DB if there are Cards that can be used
(cond-> dbs
(and (source-query-cards-exist?) virtual-db-metadata) (concat [virtual-db-metadata]))))
(and (source-query-cards-exist? :card) virtual-db-metadata) (concat [virtual-db-metadata]))))
(defn- dbs-list [& {:keys [include-tables?
include-saved-questions-db?
......@@ -285,7 +288,7 @@
"Endpoint that provides metadata for the Saved Questions 'virtual' database. Used for fooling the frontend
and allowing it to treat the Saved Questions virtual DB just like any other database."
[]
(saved-cards-virtual-db-metadata :include-tables? true, :include-fields? true))
(saved-cards-virtual-db-metadata :card :include-tables? true, :include-fields? true))
(defn- db-metadata [id include-hidden?]
(-> (api/read-check Database id)
......@@ -712,7 +715,17 @@
"Returns a list of all the schemas found for the saved questions virtual database."
[]
(when (public-settings/enable-nested-queries)
(->> (cards-virtual-tables)
(->> (cards-virtual-tables :card)
(map :schema)
distinct
(sort-by str/lower-case))))
(api/defendpoint GET ["/:virtual-db/datasets"
:virtual-db (re-pattern (str mbql.s/saved-questions-virtual-database-id))]
"Returns a list of all the datasets found for the saved questions virtual database."
[]
(when (public-settings/enable-nested-queries)
(->> (cards-virtual-tables :dataset)
(map :schema)
distinct
(sort-by str/lower-case))))
......@@ -748,9 +761,24 @@
[schema]
(when (public-settings/enable-nested-queries)
(->> (source-query-cards
:card
:additional-constraints [(if (= schema (table-api/root-collection-schema-name))
[:= :collection_id nil]
[:in :collection_id (api/check-404 (seq (db/select-ids Collection :name schema)))])
[:= :dataset false]])
(map table-api/card->virtual-table))))
(api/defendpoint GET ["/:virtual-db/datasets/:schema"
:virtual-db (re-pattern (str mbql.s/saved-questions-virtual-database-id))]
"Returns a list of Tables for the datasets virtual database."
[schema]
(when (public-settings/enable-nested-queries)
(->> (source-query-cards
:dataset
:additional-constraints [(if (= schema (table-api/root-collection-schema-name))
[:= :collection_id nil]
[:in :collection_id (api/check-404 (seq (db/select-ids Collection :name schema)))])])
[:in :collection_id (api/check-404 (seq (db/select-ids Collection :name schema)))])
[:= :dataset true]])
(map table-api/card->virtual-table))))
(api/defendpoint GET "/db-ids-with-deprecated-drivers"
......
......@@ -828,7 +828,6 @@
(let [schemas (set (mt/user-http-request :lucky :get 200 (format "database/%d/schemas" mbql.s/saved-questions-virtual-database-id)))]
(is (contains? schemas "Everything else"))
(is (contains? schemas "My Collection")))))
(testing "null and empty schemas should both come back as blank strings"
(mt/with-temp* [Database [{db-id :id}]
Table [_ {:db_id db-id, :schema ""}]
......@@ -975,6 +974,51 @@
(is (= "Not found."
(mt/user-http-request :lucky :get 404
(format "database/%d/schema/Coin Collection" mbql.s/saved-questions-virtual-database-id)))))))
(testing "should work for the datasets in the 'virtual' database"
(mt/with-temp* [Collection [coll {:name "My Collection"}]
Card [card-1 (assoc (card-with-native-query "Card 1")
:collection_id (:id coll)
:dataset true)]
Card [card-2 (assoc (card-with-native-query "Card 2")
:dataset true)]
Card [card-3 (assoc (card-with-native-query "error")
;; regular saved question should not be in the results
:dataset false)]]
;; run the cards to populate their result_metadata columns
(doseq [card [card-1 card-2]]
(mt/user-http-request :crowberto :post 202 (format "card/%d/query" (u/the-id card))))
(testing "Should be able to get datasets in a specific collection"
(is (= [{:id (format "card__%d" (:id card-1))
:db_id (mt/id)
:moderated_status nil
:display_name "Card 1"
:schema "My Collection"
:description nil}]
(mt/user-http-request :lucky :get 200
(format "database/%d/datasets/My Collection" mbql.s/saved-questions-virtual-database-id)))))
(testing "Should be able to get datasets in the root collection"
(let [response (mt/user-http-request :lucky :get 200
(format "database/%d/datasets/%s" mbql.s/saved-questions-virtual-database-id (table-api/root-collection-schema-name)))]
(is (schema= [{:id #"^card__\d+$"
:db_id s/Int
:display_name s/Str
:moderated_status (s/enum nil "verified")
:schema (s/eq (table-api/root-collection-schema-name))
:description (s/maybe s/Str)}]
response))
(is (contains? (set response)
{:id (format "card__%d" (:id card-2))
:db_id (mt/id)
:display_name "Card 2"
:moderated_status nil
:schema (table-api/root-collection-schema-name)
:description nil}))))
(testing "Should throw 404 if the schema/Collection doesn't exist"
(is (= "Not found."
(mt/user-http-request :lucky :get 404
(format "database/%d/schema/Coin Collection" mbql.s/saved-questions-virtual-database-id)))))))
(mt/with-temp* [Database [{db-id :id}]
Table [_ {:db_id db-id, :schema nil, :name "t1"}]
......
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