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

Remove Topic stuff

parent 538e34c2
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@ databaseChangeLog:
id: 32
author: camsaul
changes:
######################################## label table ########################################
- createTable:
tableName: label
columns:
......@@ -33,43 +34,7 @@ databaseChangeLog:
columns:
column:
name: slug
- createTable:
tableName: topic
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: VARCHAR(254)
constraints:
nullable: false
- column:
name: slug
type: VARCHAR(254)
constraints:
nullable: false
unique: true
- column:
name: icon
type: VARCHAR(128)
- column:
name: enabled
type: boolean
defaultValueBoolean: true
constraints:
nullable:
false
- createIndex:
tableName: topic
indexName: idx_topic_slug
columns:
column:
name: slug
######################################## card_label table ########################################
- createTable:
tableName: card_label
columns:
......@@ -95,7 +60,7 @@ databaseChangeLog:
constraints:
nullable: false
references: label(id)
foreignKeyName: fk_card_label_ref_<>_id
foreignKeyName: fk_card_label_ref_label_id
deferrable: false
initiallyDeferred: false
- addUniqueConstraint:
......@@ -114,47 +79,13 @@ databaseChangeLog:
columns:
column:
name: label_id
- createTable:
tableName: card_topic
######################################## add archived column to report_card ########################################
- addColumn:
tableName: report_card
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: card_id
type: int
constraints:
nullable: false
references: report_card(id)
foreignKeyName: fk_card_topic_ref_card_id
deferrable: false
initiallyDeferred: false
- column:
name: topic_id
type: int
name: archived
type: boolean
defaultValueBoolean: false
constraints:
nullable: false
references: topic(id)
foreignKeyName: fk_card_topic_ref_topic_id
deferrable: false
initiallyDeferred: false
- addUniqueConstraint:
tableName: card_topic
columnNames: card_id, topic_id
constraintName: unique_card_topic_card_id_topic_id
- createIndex:
tableName: card_topic
indexName: idx_card_topic_card_id
columns:
column:
name: card_id
- createIndex:
tableName: card_topic
indexName: idx_card_topic_topic_id
columns:
column:
name: topic_id
......@@ -30,6 +30,6 @@
{"include": {"file": "migrations/029_add_pulse_channel_schedule_frame.yaml"}},
{"include": {"file": "migrations/030_add_field_visibility_type.yaml"}},
{"include": {"file": "migrations/031_add_field_fk_target.yaml"}},
{"include": {"file": "migrations/032_add_label_and_topic_tables.yaml"}}
{"include": {"file": "migrations/032_add_label_and_card_label_tables.yaml"}}
]
}
......@@ -9,12 +9,10 @@
[card :refer [Card] :as card]
[card-favorite :refer [CardFavorite]]
[card-label :refer [CardLabel]]
[card-topic :refer [CardTopic]]
[common :as common]
[database :refer [Database]]
[label :refer [Label]]
[table :refer [Table]]
[topic :refer [Topic]])
[table :refer [Table]])
[metabase.util :as u]))
(defannotation CardFilterOption
......@@ -22,20 +20,6 @@
[symb value :nillable]
(checkp-contains? #{:all :mine :fav :database :table} symb (keyword value)))
;; hydrate-topics and hydrate-labels are ugly but they save us from having to do DB calls for every single Card to hydrate their Topics and Labels.
;; It would be nice if hydrate could be extended to handle MtM relationships like these automatically.
(defn- hydrate-topics
"Efficiently hydrate the `Topics` for a large collection of `Cards`."
[cards]
(let [card-topics (sel :many :fields [CardTopic :card_id :topic_id])
topic-id->topic (when (seq card-topics)
(sel :many :field->obj [Topic :id] (k/where {:id [in (set (map :topic_id card-topics))]})))
card-id->card-topics (group-by :card_id card-topics)]
(for [card cards]
(assoc card :topics (for [card-topic (card-id->card-topics (:id card))] ; TODO - do these need to be sorted ?
(topic-id->topic (:topic_id card-topic)))))))
(defn- hydrate-labels
"Efficiently hydrate the `Labels` for a large collection of `Cards`."
[cards]
......@@ -80,7 +64,6 @@
(or {:creator_id *current-user-id*}
{:public_perms [> common/perms-none]})))))
(hydrate :creator)
hydrate-topics
hydrate-labels))
(defendpoint POST "/"
......@@ -104,7 +87,7 @@
[id]
(->404 (Card id)
read-check
(hydrate :creator :can_read :can_write :dashboard_count :topics :labels)
(hydrate :creator :can_read :can_write :dashboard_count :labels)
(assoc :actor_id *current-user-id*)
(->> (events/publish-event :card-read))
(dissoc :actor_id)))
......@@ -123,7 +106,7 @@
:name name
:public_perms public_perms
:visualization_settings visualization_settings)
(events/publish-event :card-update (assoc (sel :one Card :id id) :actor_id *current-user-id*)))
(events/publish-event :card-update (assoc (Card id) :actor_id *current-user-id*)))
(defendpoint DELETE "/:id"
"Delete a `Card`."
......@@ -165,20 +148,4 @@
;; TODO - Should this endpoint return something more useful instead ?
{:status :ok})
(defendpoint POST "/:card-id/topics"
"Update the set of `Topics` that apply to a `Card`."
[card-id :as {{:keys [topic_ids]} :body}]
{topic_ids [Required ArrayOfIntegers]}
(write-check Card card-id)
(let [[topics-to-remove topics-to-add] (data/diff (set (sel :many :field [CardTopic :topic_id] :card_id card-id))
(set topic_ids))]
(println "topics-to-remove:" topics-to-remove
"topics-to-add:" topics-to-add)
(doseq [topic-id topics-to-remove]
(cascade-delete CardTopic :topic_id topic-id, :card_id card-id))
(doseq [topic-id topics-to-add]
(ins CardTopic :topic_id topic-id, :card_id card-id)))
;; TODO - Should this endpoint return something more useful instead ?
{:status :ok})
(define-routes)
......@@ -20,7 +20,6 @@
[slack :as slack]
[table :as table]
[tiles :as tiles]
[topic :as topic]
[user :as user]
[util :as util])
[metabase.middleware :as middleware]))
......@@ -56,7 +55,6 @@
(context "/slack" [] (+auth slack/routes))
(context "/table" [] (+auth table/routes))
(context "/tiles" [] (+auth tiles/routes))
(context "/topic" [] (+auth topic/routes))
(context "/user" [] (+auth user/routes))
(context "/util" [] util/routes)
(route/not-found (fn [{:keys [request-method uri]}]
......
(ns metabase.api.topic
"`/api/topic` endpoints."
(:require [compojure.core :refer [GET POST DELETE PUT]]
[korma.core :as k]
[medley.core :as m]
[metabase.api.common :refer [defendpoint define-routes write-check]]
[metabase.db :as db]
[metabase.models.topic :refer [Topic]]))
(defendpoint GET "/"
"List all topics."
[]
(db/sel :many Topic (k/order (k/sqlfn :LOWER :name))))
(defendpoint POST "/"
"Create a new topic."
[:as {{topic-name :name, icon :icon} :body}]
{topic-name [Required NonEmptyString]
icon NonEmptyString}
(db/ins Topic, :name topic-name, :icon icon, :enabled true))
(defendpoint PUT "/:id"
"Update a topic."
[id :as {{topic-name :name, icon :icon, enabled :enabled, :as body} :body}]
{topic-name NonEmptyString
icon NonEmptyString
enabled Boolean}
(write-check Topic id)
(m/mapply db/upd Topic id body)
(Topic id)) ; return the updated Topic
(defendpoint DELETE "/:id"
"Delete a topic."
[id]
(write-check Topic id)
(db/cascade-delete Topic :id id))
(define-routes)
......@@ -2,13 +2,11 @@
(:require [korma.core :as k]
[medley.core :as m]
[metabase.db :as db]
(metabase.models [card-topic :refer [CardTopic]]
[card-label :refer [CardLabel]]
(metabase.models [card-label :refer [CardLabel]]
[dependency :as dependency]
[interface :as i]
[label :refer [Label]]
[revision :as revision]
[topic :refer [Topic]])
[revision :as revision])
(metabase [query :as q]
[util :as u])))
......@@ -35,16 +33,6 @@
first
:dashboards))
(defn topics
"Return `Topics` for CARD."
{:hydrate :topics}
[{:keys [id]}]
(if-let [topic-ids (seq (db/sel :many :field [CardTopic :topic_id] :card_id id))]
(db/sel :many Topic
(k/where {:id [in topic-ids]})
(k/order (k/sqlfn :LOWER :name)))
[]))
(defn labels
"Return `Labels` for CARD."
{:hydrate :labels}
......@@ -61,8 +49,7 @@
(db/cascade-delete 'DashboardCardSeries :card_id id)
(db/cascade-delete 'DashboardCard :card_id id)
(db/cascade-delete 'CardFavorite :card_id id)
(db/cascade-delete 'CardLabel :card_id id)
(db/cascade-delete 'CardTopic :card_id id))
(db/cascade-delete 'CardLabel :card_id id))
;;; ## ---------------------------------------- REVISIONS ----------------------------------------
......
(ns metabase.models.card-topic
(:require [metabase.models.interface :as i]
[metabase.util :as u]))
(i/defentity CardTopic :card_topic)
(u/strict-extend (class CardTopic)
i/IEntity
(merge i/IEntityDefaults
{:can-read? (constantly true)
:can-write? (constantly true)}))
......@@ -6,38 +6,13 @@
(i/defentity Label :label)
(defn- num-slugs-starting-with
"Return the number of `Label` slugs that start with a given PREFIX string."
[prefix]
(:count (first (k/select Label
(k/aggregate (count :*) :count)
(k/where {:slug [like (str prefix \%)]})))))
(defn- uniqify-slug
"Make sure SLUG is unique, and append a number suffix to it otherwise.
;; my_cool_slug is unused
(uniqify-slug \"my_cool_slug\") -> \"my_cool_slug\"
;; my_cool_slug is already used
(uniqify-slug \"my_cool_slug\") -> \"my_cool_slug_2\""
[slug]
(if-not (db/exists? Label :slug slug)
slug
;; recur just to double-check the uniqified slug is actually unique
(uniqify-slug (str slug \_ (inc (num-slugs-starting-with slug))))))
(def ^:private slugify (comp uniqify-slug u/slugify))
(defn- pre-insert [{label-name :name, :as label}]
;; TODO - it probably makes sense to check if the slug is already being used
;; and add a unique suffix if so, e.g. `cool_topic` and `cool_topic_2`
(assoc label :slug (slugify label-name)))
(assoc label :slug (u/slugify label-name)))
(defn- pre-update [{label-name :name, :as label}]
(if-not label-name
label
(assoc label :slug (slugify label-name))))
(assoc label :slug (u/slugify label-name))))
(defn- pre-cascade-delete [{:keys [id]}]
(db/cascade-delete 'CardLabel :label_id id))
......
(ns metabase.models.topic
(:require [korma.core :as k]
[metabase.db :as db]
[metabase.models.interface :as i]
[metabase.util :as u]))
(i/defentity Topic :topic)
(defn- num-slugs-starting-with
"Return the number of `Topic` slugs that start with a given PREFIX string."
[prefix]
(:count (first (k/select Topic
(k/aggregate (count :*) :count)
(k/where {:slug [like (str prefix \%)]})))))
(defn- uniqify-slug
"Make sure SLUG is unique, and append a number suffix to it otherwise.
;; my_cool_slug is unused
(uniqify-slug \"my_cool_slug\") -> \"my_cool_slug\"
;; my_cool_slug is already used
(uniqify-slug \"my_cool_slug\") -> \"my_cool_slug_2\""
[slug]
(if-not (db/exists? Topic :slug slug)
slug
;; recur just to double-check the uniqified slug is actually unique
(uniqify-slug (str slug \_ (inc (num-slugs-starting-with slug))))))
(def ^:private slugify (comp uniqify-slug u/slugify))
(defn- pre-insert [{topic-name :name, :as topic}]
;; TODO - it probably makes sense to check if the slug is already being used
;; and add a unique suffix if so, e.g. `cool_topic` and `cool_topic_2`
(assoc topic :slug (slugify topic-name)))
(defn- pre-update [{topic-name :name, :as topic}]
(if-not topic-name
topic
(assoc topic :slug (slugify topic-name))))
(defn- pre-cascade-delete [{:keys [id]}]
(db/cascade-delete 'CardTopic :topic_id id))
(u/strict-extend (class Topic)
i/IEntity
(merge i/IEntityDefaults
{:can-read? (constantly true)
:can-write? (constantly true)
:pre-insert pre-insert
:pre-update pre-update
:pre-cascade-delete pre-cascade-delete}))
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