Skip to content

Commit

Permalink
mark email types
Browse files Browse the repository at this point in the history
  • Loading branch information
salsakran authored and tlrobinson committed Nov 6, 2016
1 parent c614d95 commit b199bff
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/metabase/sync_database/analyze.clj
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,45 @@
(log/debug (u/format-color 'green "Field '%s' looks like it contains valid JSON objects. Setting special_type to :type/JSON." (field/qualified-name field)))
(assoc field-stats :special-type :type/JSON, :preview-display false)))))

(defn valid-email?
[email]
(let [pattern #"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"]
(and (string? email) (re-matches pattern email))))


(defn- values-are-valid-emails?
"`true` if at every item in VALUES is `nil` or a valid string-encoded JSON dictionary or array, and at least one of those is non-nil."
[values]
(try
(loop [at-least-one-non-nil-value? false, [val & more] values]
(cond
(and (not val)
(not (seq more))) at-least-one-non-nil-value?
(s/blank? val) (recur at-least-one-non-nil-value? more)
;; If val is non-nil, check that it's a JSON dictionary or array. We don't want to mark Fields containing other
;; types of valid JSON values as :json (e.g. a string representation of a number or boolean)
:else (do (assert (valid-email? val))
(recur true more))))
(catch Throwable _
false)))

(defn- test:email-special-type
"Mark FIELD as `:json` if it's textual, doesn't already have a special type, the majority of it's values are non-nil, and all of its non-nil values
are valid serialized JSON dictionaries or arrays."
[driver field field-stats]
(if-not (and (not (:special_type field))
(not (isa? (:base_type field) :type/Text)))
;; this field isn't suited for this test
field-stats
;; check for json values
(if-not (values-are-valid-emails? (take driver/max-sync-lazy-seq-results (driver/field-values-lazy-seq driver field)))
field-stats
(do
(log/debug (u/format-color 'green "Field '%s' looks like it contains valid email addresses. Setting special_type to :type/Email." (field/qualified-name field)))
(assoc field-stats :special-type :type/Email, :preview-display false)))))



(defn- test:new-field
"Do the various tests that should only be done for a new `Field`.
We only run most of the field analysis work when the field is NEW in order to favor performance of the sync process."
Expand Down
9 changes: 9 additions & 0 deletions test/metabase/sync_database/analyze_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,12 @@
(expect false (values-are-valid-json? ["100"]))
(expect false (values-are-valid-json? ["true"]))
(expect false (values-are-valid-json? ["false"]))

;; Check that things that are valid emails are marked as Emails
(expect true (values-are-valid-email? ["helper@metabase.com"]))
(expect true (values-are-valid-email? ["helper@metabase.com", "someone@here.com", "help@nope.com"]))

(expect false (values-are-valid-email? ["\"A string should not cause a Field to be marked as email\""]))
(expect false (values-are-valid-email? [100]))
(expect false (values-are-valid-email? ["true"]))
(expect false (values-are-valid-email? ["false"]))

0 comments on commit b199bff

Please sign in to comment.