Skip to content
Snippets Groups Projects
Commit 93da556a authored by Cam Saul's avatar Cam Saul
Browse files

actually, no point in putting the 'settings' table in the DB

parent 824c02a0
Branches
Tags
No related merge requests found
......@@ -8,29 +8,6 @@
{
"createTable": {
"tableName": "setting",
"columns": [
{
"column": {
"name": "key",
"type": "varchar(254)",
"constraints": {
"primaryKey": true,
"nullable": false
}
}
},
{
"column": {
"name": "description",
"type": "varchar(254)"
}
}
]
}
},
{
"createTable": {
"tableName": "setting_value",
"columns": [
{
"column": {
......@@ -50,7 +27,7 @@
"constraints": {
"nullable": false,
"references": "core_organization(id)",
"foreignKeyName": "fk_setting_value_ref_organization_id",
"foreignKeyName": "fk_setting_ref_organization_id",
"deferrable": false,
"initiallyDeferred": false
}
......@@ -58,14 +35,10 @@
},
{
"column": {
"name": "setting_key",
"name": "key",
"type": "varchar(254)",
"constraints": {
"nullable": false,
"references": "setting(key)",
"foreignKeyName": "fk_setting_value_ref_setting_key",
"deferrable": false,
"initiallyDeferred": false
"nullable": false
}
}
},
......@@ -83,15 +56,15 @@
},
{
"addUniqueConstraint": {
"tableName": "setting_value",
"constraintName": "idx_unique_setting_id_organization_id",
"columnNames": "setting_key, organization_id"
"tableName": "setting",
"constraintName": "idx_setting_unique_key_organization_id",
"columnNames": "key, organization_id"
}
},
{
"createIndex": {
"tableName": "setting_value",
"indexName": "idx_setting_value_organization_id",
"tableName": "setting",
"indexName": "idx_setting_organization_id",
"columns": [
{
"column": {
......@@ -104,8 +77,8 @@
},
{
"createIndex": {
"tableName": "setting_value",
"indexName": "idx_setting_value_organization_id_setting_key",
"tableName": "setting",
"indexName": "idx_setting_organization_id_key",
"columns": [
{
"column": {
......@@ -115,7 +88,7 @@
},
{
"column": {
"name": "setting_key",
"name": "key",
"type": "varchar(254)"
}
}
......
......@@ -3,6 +3,6 @@
{"include": {"file": "migrations/liquibase_0.1.0.json"}},
{"include": {"file": "migrations/liquibase_0.5.0.json"}},
{"include": {"file": "migrations/liquibase_0.6.0.json"}},
{"include": {"file": "migrations/004_settings.json"}}
{"include": {"file": "migrations/004_add_setting_table.json"}}
]
}
......@@ -2,56 +2,59 @@
(:refer-clojure :exclude [get set])
(:require [clojure.core.match :refer [match]]
[korma.core :refer :all :exclude [delete]]
[metabase.db :refer [sel del post-select]]))
[metabase.db :refer [sel del]]))
(declare Setting
SettingValue
cached-setting-values
setup)
restore-cache-if-needed)
;; # PUBLIC
;; ## ACCESSORS
(defn get
"Fetch setting with key K for Org.
Cached lookup time is ~70 s, compared to ~1100 s for DB lookup."
"Fetch value of `Setting` for `Org`.
Cached lookup time is ~60µs, compared to ~1800µs for DB lookup."
[org-id k]
{:pre [(integer? org-id)
(keyword? k)]}
(setup)
(restore-cache-if-needed)
(or (@cached-setting-values [k org-id])
(when-let [v (sel :one :field [SettingValue :value] :setting_key (name k) :organization_id org-id)]
(when-let [v (sel :one :field [Setting :value] :key (name k) :organization_id org-id)]
(swap! cached-setting-values assoc [k org-id] v)
v)))
(defn set [org-id k v]
(defn set
"Set the value of `Setting` for `Org`.
(set org-id :mandrill-api-key \"xyz123\")"
[org-id k v]
{:pre [(integer? org-id)
(keyword? k)
(string? v)]}
(if (get org-id k) (update SettingValue
(if (get org-id k) (update Setting
(set-fields {:value v})
(where {:setting_key (name k)
(where {:key (name k)
:organization_id org-id}))
(insert SettingValue
(values {:setting_key (name k)
(insert Setting
(values {:key (name k)
:organization_id org-id
:value v})))
(setup)
(restore-cache-if-needed)
(swap! cached-setting-values assoc [k org-id] v)
v)
(defn delete [org-id k]
(defn delete
"Delete a `Setting` value for `Org`."
[org-id k]
{:pre [(integer? org-id)
(keyword? k)]}
(setup)
(restore-cache-if-needed)
(swap! cached-setting-values dissoc [k org-id])
(del SettingValue :setting_key (name k) :organization_id org-id))
(del Setting :key (name k) :organization_id org-id))
;; ## DEFSETTING
(def defsetting-dirty? (atom false))
(defmacro defsetting
"Defines a new `Setting` that will be added to the DB at some point in the future.
Conveniently can be used as a getter/setter as well:
......@@ -69,15 +72,16 @@
(get org-id# ~setting-key))
([org-id# value#]
(set org-id# ~setting-key value#)))
(alter-meta! #'~nm assoc :is-setting? true)
(reset! metabase.models.setting/defsetting-dirty? true))))
(alter-meta! #'~nm assoc :is-setting? true))))
;; ## ALL SETTINGS (ETC)
(defn all [org-id]
(defn all
"Return all `Settings` for `Org`."
[org-id]
{:pre [(integer? org-id)]}
(setup)
(restore-cache-if-needed)
(->> @cached-setting-values
(map (fn [[[k o-id] v]]
(when (= org-id o-id)
......@@ -85,9 +89,23 @@
(filter identity)
(reduce merge {})))
(defn all-with-descriptions [org-id]
(defn settings-list
"Return a list of all Settings (as created with `defsetting`)."
[]
(->> (all-ns)
(mapcat ns-interns)
vals
(map meta)
(filter :is-setting?)
(map (fn [{k :name desc :doc}]
{:key (keyword k)
:description desc}))))
(defn all-with-descriptions
"Return a combined list of all `Settings` and values for `Org`, if they exist."
[org-id]
(let [settings-for-org (all org-id)]
(->> (sel :many Setting)
(->> (settings-list)
(map (fn [{k :key :as setting}]
(assoc setting
:value (k settings-for-org)))))))
......@@ -95,41 +113,10 @@
;; # IMPLEMENTATION
(declare create-settings-if-needed
restore-cache-if-needed)
(defn- setup []
(create-settings-if-needed)
(restore-cache-if-needed))
;; ## DEFSETTING
(defn- create-settings-if-needed []
(when @defsetting-dirty?
(println "RECREATING SETTINGS...")
(reset! defsetting-dirty? false)
(let [existing-settings (->> (sel :many :field [Setting :key])
(map name)
clojure.core/set)]
(->> (all-ns)
(mapcat ns-interns)
vals
(map meta)
(filter :is-setting?)
(map (fn [{k :name desc :doc}]
{:key (name k)
:description desc}))
(filter #((complement contains?) existing-settings (:key %)))
(map (fn [setting]
(insert Setting (values setting))))))))
;; ## ACCESSORS
(defn- restore-cache-if-needed []
(when-not @cached-setting-values
(reset! cached-setting-values (->> (sel :many SettingValue)
(map (fn [{k :setting_key org :organization_id v :value}]
(reset! cached-setting-values (->> (sel :many Setting)
(map (fn [{k :key org :organization_id v :value}]
{[(keyword k) org] v}))
(reduce merge {})))))
......@@ -138,10 +125,3 @@
(defentity ^:private Setting
(table :setting))
(defmethod post-select Setting [_ {k :key :as setting}]
(assoc setting
:key (keyword k)))
(defentity ^:private SettingValue
(table :setting_value))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment