;; and there's actually a row in the DB that's not in the cache for some reason. Go ahead and update the
;; existing value and log a warning
(catchThrowablee
(log/warn"Error INSERTing a new Setting:"(.getMessagee)"\nAssuming Setting already exists in DB and updating existing value.")
(log/warn"Error INSERTing a new Setting:"(.getMessagee)
"\nAssuming Setting already exists in DB and updating existing value.")
(update-setting!setting-namenew-value))))
(s/defn^:always-validateset-string!
"Set string value of SETTING-OR-NAME. A `nil` or empty NEW-VALUE can be passed to unset (i.e., delete) SETTING-OR-NAME."
"Set string value of SETTING-OR-NAME. A `nil` or empty NEW-VALUE can be passed to unset (i.e., delete)
SETTING-OR-NAME."
[setting-or-name,new-value:-(s/maybes/Str)]
(let[new-value(when(seqnew-value)
new-value)
...
...
@@ -225,7 +232,8 @@
new-value))
(defnset-boolean!
"Set the value of boolean SETTING-OR-NAME. NEW-VALUE can be nil, a boolean, or a string representation of one, such as `\"true\"` or `\"false\"` (these strings are case-insensitive)."
"Set the value of boolean SETTING-OR-NAME. NEW-VALUE can be nil, a boolean, or a string representation of one, such
as `\"true\"` or `\"false\"` (these strings are case-insensitive)."
"Set the value of SETTING-OR-NAME. What this means depends on the Setting's `:setter`; by default, this just updates the Settings cache and writes its value to the DB.
"Set the value of SETTING-OR-NAME. What this means depends on the Setting's `:setter`; by default, this just updates
the Settings cache and writes its value to the DB.
;; indentation below is intentional to make it clearer what shape the generated documentation is going to take. Turn on auto-complete-mode in Emacs and see for yourself!
;; indentation below is intentional to make it clearer what shape the generated documentation is going to take.
;; Turn on auto-complete-mode in Emacs and see for yourself!
:doc(str/join"\n"[description
""
(format"`%s` is a %s `Setting`. You can get its value by calling:"(setting-namesetting)(namesetting-type))
...
...
@@ -331,7 +345,8 @@
([]
(getsetting))
([new-value]
;; need to qualify this or otherwise the reader gets this confused with the set! used for things like (set! *warn-on-reflection* true)
;; need to qualify this or otherwise the reader gets this confused with the set! used for things like
;; (set! *warn-on-reflection* true)
;; :refer-clojure :exclude doesn't seem to work in this case
(metabase.models.setting/set!settingnew-value))))
...
...
@@ -344,20 +359,23 @@
(mandrill-api-key new-value) ; update the value
(mandrill-api-key nil) ; delete the value
A setting can be set from the SuperAdmin page or via the corresponding env var,
eg. `MB_MANDRILL_API_KEY` for the example above.
A setting can be set from the SuperAdmin page or via the corresponding env var, eg. `MB_MANDRILL_API_KEY` for the
example above.
You may optionally pass any of the OPTIONS below:
* `:default` - The default value of the setting. (default: `nil`)
* `:type` - `:string` (default), `:boolean`, `:integer`, or `:json`. Non-`:string` settings have special default getters and setters that automatically coerce values to the correct types.
* `:internal?` - This `Setting` is for internal use and shouldn't be exposed in the UI (i.e., not
returned by the corresponding endpoints). Default: `false`
* `:getter` - A custom getter fn, which takes no arguments. Overrides the default implementation.
(This can in turn call functions in this namespace like `get-string` or `get-boolean` to invoke the default getter behavior.)
* `:setter` - A custom setter fn, which takes a single argument. Overrides the default implementation.
(This can in turn call functions in this namespace like `set-string!` or `set-boolean!` to invoke the default setter behavior.
Keep in mind that the custom setter may be passed `nil`, which should clear the values of the Setting.)"
* `:default` - The default value of the setting. (default: `nil`)
* `:type` - `:string` (default), `:boolean`, `:integer`, or `:json`. Non-`:string` settings have special
default getters and setters that automatically coerce values to the correct types.
* `:internal?` - This `Setting` is for internal use and shouldn't be exposed in the UI (i.e., not returned by the
corresponding endpoints). Default: `false`
* `:getter` - A custom getter fn, which takes no arguments. Overrides the default implementation. (This can in
turn call functions in this namespace like `get-string` or `get-boolean` to invoke the default
getter behavior.)
* `:setter` - A custom setter fn, which takes a single argument. Overrides the default implementation. (This
can in turn call functions in this namespace like `set-string!` or `set-boolean!` to invoke the
default setter behavior. Keep in mind that the custom setter may be passed `nil`, which should
;; TODO - This event is no longer neccessary or desirable. This is used in only a single place, to stop or restart the MetaBot when settings are updated;
;; this only works if the setting is updated via this specific function. Instead, we should define a custom setter for the relevant setting that additionally
;; performs the desired operations when the value is updated. This pattern is easier to understand, works no matter how the setting is changed, and doesn't run when
;; irrelevant changes (to other settings) are made.
;; TODO - This event is no longer neccessary or desirable. This is used in only a single place, to stop or restart
;; the MetaBot when settings are updated ; this only works if the setting is updated via this specific function.
;; Instead, we should define a custom setter for the relevant setting that additionally performs the desired
;; operations when the value is updated. This pattern is easier to understand, works no matter how the setting is
;; changed, and doesn't run when irrelevant changes (to other settings) are made.