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

Merge pull request #513 from metabase/human_readable_names

Add :human_readable_name to Table and Field API responses
parents f388ed3f 67400ac4
No related branches found
No related tags found
No related merge requests found
......@@ -112,7 +112,8 @@
"Get a list of all `Tables` in `Database`."
[id]
(read-check Database id)
(sel :many Table :db_id id :active true (order :name)))
(-> (sel :many Table :db_id id :active true (order :name))
(hydrate :human_readable_name)))
(defendpoint GET "/:id/idfields"
"Get a list of all primary key `Fields` for `Database`."
......
......@@ -20,14 +20,13 @@
"Get all `Tables`."
[]
(-> (sel :many Table :active true (order :name :ASC))
(hydrate :db)
(hydrate :db :human_readable_name)
;; if for some reason a Table doesn't have rows set then set it to 0 so UI doesn't barf
(#(map (fn [table]
(cond-> table
(not (:rows table)) (assoc :rows 0)))
%))))
(defendpoint GET "/:id"
"Get `Table` with ID."
[id]
......@@ -50,7 +49,8 @@
"Get all `Fields` for `Table` with ID."
[id]
(read-check Table id)
(sel :many Field :table_id id, :active true, :field_type [not= "sensitive"], (order :name :ASC)))
(-> (sel :many Field :table_id id, :active true, :field_type [not= "sensitive"], (order :name :ASC))
(hydrate :human_readable_name)))
(defendpoint GET "/:id/query_metadata"
"Get metadata about a `Table` useful for running queries.
......
(ns metabase.models.common
(:require [metabase.api.common :refer [*current-user* *current-user-id* check]]
(:require [clojure.string :as s]
[metabase.api.common :refer [*current-user* *current-user-id* check]]
[metabase.util :as u]))
(def timezones
......@@ -64,7 +65,21 @@
Note that these delays depend upon the presence of `creator_id`, and `public_perms` fields in OBJ."
[obj]
(u/assoc* obj
:public-permissions-set (delay (public-permissions <>))
:user-permissions-set (delay (user-permissions <>))
:can_read (delay (user-can? :read <>))
:can_write (delay (user-can? :write <>))))
:public-permissions-set (delay (public-permissions <>))
:user-permissions-set (delay (user-permissions <>))
:can_read (delay (user-can? :read <>))
:can_write (delay (user-can? :write <>))))
(defn name->human-readable-name
"Convert a string NAME of some object like a `Table` or `Field` to one more friendly to humans.
(name->human-readable-name \"admin_users\") -> \"Admin Users\""
[^String n]
(when-let [n (some-> n
(s/replace #"(?:-|_id)$" "") ; strip off any trailing _id or -id suffix
(s/split #"_|-"))] ; explode string on underscores and hyphens
(->> (for [[first-letter & rest-letters] n] ; for each part of the string,
(apply str (s/upper-case first-letter) (map s/lower-case rest-letters))) ; upcase the first char and downcase the rest
(interpose " ") ; add a space between each part
(apply str)))) ; convert back to a single string
......@@ -2,7 +2,8 @@
(:require [korma.core :refer :all]
[metabase.api.common :refer [check]]
[metabase.db :refer :all]
(metabase.models [database :refer [Database]]
(metabase.models [common :as common]
[database :refer [Database]]
[field-values :refer [field-should-have-field-values? create-field-values create-field-values-if-needed]]
[hydrate :refer [hydrate]]
[foreign-key :refer [ForeignKey]])
......@@ -91,11 +92,13 @@
(defmethod post-select Field [_ {:keys [table_id] :as field}]
(u/assoc* field
:table (delay (sel :one 'metabase.models.table/Table :id table_id))
:db (delay @(:db @(:table <>)))
:target (delay (field->fk-field field))
:can_read (delay @(:can_read @(:table <>)))
:can_write (delay @(:can_write @(:table <>)))))
:table (delay (sel :one 'metabase.models.table/Table :id table_id))
:db (delay @(:db @(:table <>)))
:target (delay (field->fk-field field))
:can_read (delay @(:can_read @(:table <>)))
:can_write (delay @(:can_write @(:table <>)))
:human_readable_name (when (name :field)
(delay (common/name->human-readable-name (:name field))))))
(defmethod pre-insert Field [_ field]
(let [defaults {:active true
......
(ns metabase.models.table
(:require [korma.core :refer :all]
[metabase.db :refer :all]
(metabase.models [database :as db]
(metabase.models [common :as common]
[database :as db]
[field :refer [Field]]
[field-values :refer [FieldValues]])
[metabase.util :as u]))
......@@ -20,20 +21,22 @@
; also missing :active and :pk_field
(defmethod post-select Table [_ {:keys [id db db_id description] :as table}]
(u/assoc* table
:db (or db (delay (sel :one db/Database :id db_id)))
:fields (delay (sel :many Field :table_id id :active true (order :position :ASC) (order :name :ASC)))
:field_values (delay
(let [field-ids (sel :many :field [Field :id]
:table_id id
:active true
:field_type [not= "sensitive"]
(order :position :asc)
(order :name :asc))]
(sel :many :field->field [FieldValues :field_id :values] :field_id [in field-ids])))
:description (u/jdbc-clob->str description)
:pk_field (delay (:id (sel :one :fields [Field :id] :table_id id (where {:special_type "id"}))))
:can_read (delay @(:can_read @(:db <>)))
:can_write (delay @(:can_write @(:db <>)))))
:db (or db (delay (sel :one db/Database :id db_id)))
:fields (delay (sel :many Field :table_id id :active true (order :position :ASC) (order :name :ASC)))
:field_values (delay
(let [field-ids (sel :many :field [Field :id]
:table_id id
:active true
:field_type [not= "sensitive"]
(order :position :asc)
(order :name :asc))]
(sel :many :field->field [FieldValues :field_id :values] :field_id [in field-ids])))
:description (u/jdbc-clob->str description)
:pk_field (delay (:id (sel :one :fields [Field :id] :table_id id (where {:special_type "id"}))))
:can_read (delay @(:can_read @(:db <>)))
:can_write (delay @(:can_write @(:db <>)))
:human_readable_name (when (:name table)
(delay (common/name->human-readable-name (:name table))))))
(defmethod pre-cascade-delete Table [_ {:keys [id] :as table}]
......
......@@ -158,11 +158,11 @@
(expect
(let [db-id (db-id)]
[(match-$ (sel :one Table :id (id :categories))
{:description nil, :entity_type nil, :name "CATEGORIES", :rows 75, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $})
{:description nil, :entity_type nil, :name "CATEGORIES", :rows 75, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $, :human_readable_name "Categories"})
(match-$ (sel :one Table :id (id :checkins))
{:description nil, :entity_type nil, :name "CHECKINS", :rows 1000, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $})
{:description nil, :entity_type nil, :name "CHECKINS", :rows 1000, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $, :human_readable_name "Checkins"})
(match-$ (sel :one Table :id (id :users))
{:description nil, :entity_type nil, :name "USERS", :rows 15, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $})
{:description nil, :entity_type nil, :name "USERS", :rows 15, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $, :human_readable_name "Users"})
(match-$ (sel :one Table :id (id :venues))
{:description nil, :entity_type nil, :name "VENUES", :rows 100, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $})])
{:description nil, :entity_type nil, :name "VENUES", :rows 100, :updated_at $, :entity_name nil, :active true, :id $, :db_id db-id, :created_at $, :human_readable_name "Venues"})])
((user->client :rasta) :get 200 (format "meta/db/%d/tables" (db-id))))
......@@ -10,7 +10,7 @@
[table :refer [Table]])
[metabase.test.data :refer :all]
(metabase.test.data [data :as data]
[datasets :as datasets, :refer [*dataset* with-dataset-when-testing]]
[datasets :as datasets]
[users :refer :all])
[metabase.test.util :refer [match-$ expect-eval-actual-first]]))
......@@ -25,14 +25,32 @@
;; ## GET /api/meta/table?org
;; These should come back in alphabetical order and include relevant metadata
(expect (set (mapcat (fn [dataset-name]
(with-dataset-when-testing dataset-name
(let [db-id (:id (datasets/db *dataset*))]
[{:name (datasets/format-name *dataset* "categories"), :db_id db-id, :active true, :rows 75, :id (datasets/table-name->id *dataset* :categories)}
{:name (datasets/format-name *dataset* "checkins"), :db_id db-id, :active true, :rows 1000, :id (datasets/table-name->id *dataset* :checkins)}
{:name (datasets/format-name *dataset* "users"), :db_id db-id, :active true, :rows 15, :id (datasets/table-name->id *dataset* :users)}
{:name (datasets/format-name *dataset* "venues"), :db_id db-id, :active true, :rows 100, :id (datasets/table-name->id *dataset* :venues)}])))
@datasets/test-dataset-names))
(expect (set (reduce concat (for [dataset-name @datasets/test-dataset-names]
(datasets/with-dataset-when-testing dataset-name
[{:name (format-name "categories")
:human_readable_name "Categories"
:db_id (db-id)
:active true
:rows 75
:id (id :categories)}
{:name (format-name "checkins")
:human_readable_name "Checkins"
:db_id (db-id)
:active true
:rows 1000
:id (id :checkins)}
{:name (format-name "users")
:human_readable_name "Users"
:db_id (db-id)
:active true
:rows 15
:id (id :users)}
{:name (format-name "venues")
:human_readable_name "Venues"
:db_id (db-id)
:active true
:rows 100
:id (id :venues)}]))))
(->> ((user->client :rasta) :get 200 "meta/table")
(map #(dissoc % :db :created_at :updated_at :entity_name :description :entity_type))
set))
......@@ -64,31 +82,33 @@
;; ## GET /api/meta/table/:id/fields
(expect [(match-$ (sel :one Field :id (id :categories :id))
{:description nil
:table_id (id :categories)
:special_type "id"
:name "ID"
:updated_at $
:active true
:id (id :categories :id)
:field_type "info"
:position 0
:preview_display true
:created_at $
:base_type "BigIntegerField"})
{:description nil
:table_id (id :categories)
:special_type "id"
:name "ID"
:human_readable_name "Id"
:updated_at $
:active true
:id (id :categories :id)
:field_type "info"
:position 0
:preview_display true
:created_at $
:base_type "BigIntegerField"})
(match-$ (sel :one Field :id (id :categories :name))
{:description nil
:table_id (id :categories)
:special_type "name"
:name "NAME"
:updated_at $
:active true
:id (id :categories :name)
:field_type "info"
:position 0
:preview_display true
:created_at $
:base_type "TextField"})]
{:description nil
:table_id (id :categories)
:special_type "name"
:name "NAME"
:human_readable_name "Name"
:updated_at $
:active true
:id (id :categories :name)
:field_type "info"
:position 0
:preview_display true
:created_at $
:base_type "TextField"})]
((user->client :rasta) :get 200 (format "meta/table/%d/fields" (id :categories))))
;; ## GET /api/meta/table/:id/query_metadata
......
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