Skip to content

Commit

Permalink
Merge pull request #62 from metabase/potemkin
Browse files Browse the repository at this point in the history
Use Potemkin to define model record types in defmodel macro
  • Loading branch information
camsaul authored Aug 19, 2019
2 parents 58b90df + 3bcc9d9 commit fa0ffb2
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 56 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ profiles.clj
/build.xml
/*.iml
.envrc
/.eastwood
107 changes: 75 additions & 32 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,36 +1,79 @@
(defproject toucan "1.13.0"
(defproject toucan "1.14.0-SNAPSHOT"
:description "Functionality for defining your application's models and querying the database."
:url "https://github.com/metabase/toucan"
:license {:name "Eclipse Public License"
:url "https://raw.githubusercontent.com/metabase/toucan/master/LICENSE.txt"}
:url "https://raw.githubusercontent.com/metabase/toucan/master/LICENSE.txt"}
:min-lein-version "2.5.0"
:dependencies [[org.clojure/java.classpath "0.3.0"]
[org.clojure/java.jdbc "0.7.9"]
[org.clojure/tools.logging "0.4.1"]
[org.clojure/tools.namespace "0.2.10"]
[honeysql "0.9.4"]]
:aliases {"bikeshed" ["bikeshed" "--max-line-length" "118" "--var-redefs" "false"]
"lint" ["do" ["eastwood"] ["bikeshed"] ["docstring-checker"] ["check-namespace-decls"]]
"test" ["expectations"]
"start-db" ["shell" "./start-db"] ; `lein start-db` and stop-db are conveniences for running a test database via Docker
"stop-db" ["shell" "docker" "stop" "toucan_test"]}
:profiles {:dev {:dependencies [[org.clojure/clojure "1.10.0"]
[expectations "2.1.10"]
[postgresql "9.3-1102.jdbc41"]]
:plugins [[docstring-checker "1.0.3"]
[jonase/eastwood "0.3.4"
:exclusions [org.clojure/clojure]]
[lein-bikeshed "0.5.1"]
[lein-check-namespace-decls "1.0.1"]
[lein-expectations "0.0.8"]
[lein-shell "0.5.0"]]
:jvm-opts ["-Xverify:none"]
:eastwood {:add-linters [:unused-locals
:unused-private-vars]
:exclude-namespaces [:test-paths]}}}
:docstring-checker {:include [#"^toucan"]
:exclude [#"test"]}
:deploy-repositories [["clojars" {:url "https://clojars.org/repo"
:username :env/clojars_username
:password :env/clojars_password
:sign-releases false}]])

:aliases
{"test" ["with-profile" "+expectations" "expectations"]
"bikeshed" ["with-profile" "+bikeshed" "bikeshed" "--max-line-length" "120"]
"check-namespace-decls" ["with-profile" "+check-namespace-decls" "check-namespace-decls"]
"eastwood" ["with-profile" "+eastwood" "eastwood"]
"docstring-checker" ["with-profile" "+docstring-checker" "docstring-checker"]
;; `lein lint` will run all linters
"lint" ["do" ["eastwood"] ["bikeshed"] ["check-namespace-decls"] ["docstring-checker"]]
;; `lein start-db` and stop-db are conveniences for running a test database via Docker
"start-db" ["shell" "./start-db"]
"stop-db" ["shell" "docker" "stop" "toucan_test"]}

:dependencies
[[org.clojure/java.classpath "0.3.0"]
[org.clojure/java.jdbc "0.7.9"]
[org.clojure/tools.logging "0.5.0"]
[org.clojure/tools.namespace "0.3.1"]
[honeysql "0.9.5"]]

:profiles
{:dev
{:dependencies
[[org.clojure/clojure "1.10.1"]
[expectations "2.2.0-beta2"]
[org.postgresql/postgresql "42.2.5"]]

:plugins
[[lein-check-namespace-decls "1.0.1"]
[lein-expectations "0.0.8"]
[lein-shell "0.5.0"]]

:injections
[(require 'expectations)
(#'expectations/disable-run-on-shutdown)]

:jvm-opts
["-Xverify:none"]}

:expectations
{:plugins [[lein-expectations "0.0.8" :exclusions [expectations]]]}

:eastwood
{:plugins
[[jonase/eastwood "0.3.6" :exclusions [org.clojure/clojure]]]

:add-linters
[:unused-private-vars
:unused-namespaces
:unused-fn-args
:unused-locals]}

:docstring-checker
{:plugins
[[docstring-checker "1.0.3"]]

:docstring-checker
{:exclude [#"test"]}}

:bikeshed
{:plugins
[[lein-bikeshed "0.5.2"]]}

:check-namespace-decls
{:plugins [[lein-check-namespace-decls "1.0.2"]]
:check-namespace-decls {:prefix-rewriting true}}}

:deploy-repositories
[["clojars"
{:url "https://clojars.org/repo"
:username :env/clojars_username
:password :env/clojars_password
:sign-releases false}]])
1 change: 1 addition & 0 deletions src/toucan/models.clj
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@
defrecord-form `(defrecord ~instance []
clojure.lang.Named
(~'getName [~'_] ~(name model))
(~'getNamespace [~'_] ~(name (ns-name *ns*)))

clojure.lang.IFn
~@(ifn-invoke-forms)
Expand Down
7 changes: 4 additions & 3 deletions test/toucan/db_test.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns toucan.db-test
(:require [clojure.java.jdbc :as jdbc]
[expectations :refer :all]
[honeysql.core :as hsql]
[toucan
[db :as db]
[test-setup :as test]]
Expand Down Expand Up @@ -295,7 +296,7 @@
(expect
[4 5]
(test/with-clean-db
(db/simple-insert-many! User [{:first-name "Grass" :last-name #sql/call [:upper "Hopper"]}
(db/simple-insert-many! User [{:first-name "Grass" :last-name (hsql/call :upper "Hopper")}
{:first-name "Ko" :last-name "Libri"}])))

;;; Test insert-many!
Expand All @@ -304,7 +305,7 @@
(expect
[4 5]
(test/with-clean-db
(db/insert-many! User [{:first-name "Grass" :last-name #sql/call [:upper "Hopper"]}
(db/insert-many! User [{:first-name "Grass" :last-name (hsql/call :upper "Hopper")}
{:first-name "Ko" :last-name "Libri"}])))

;; It must call pre-insert hooks
Expand Down Expand Up @@ -332,7 +333,7 @@
(expect
#toucan.test_models.user.UserInstance{:id 4, :first-name "Grass", :last-name "HOPPER"}
(test/with-clean-db
(db/insert! User {:first-name "Grass" :last-name #sql/call [:upper "Hopper"]})))
(db/insert! User {:first-name "Grass" :last-name (hsql/call :upper "Hopper")})))

;; get-inserted-id shouldn't fail if nothing is returned for some reason
(expect
Expand Down
4 changes: 0 additions & 4 deletions test/toucan/models_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,6 @@
(set (Category))))

;; Test default-fields
;; by default Venue doesn't return :created-at or :updated-at
(expect
#toucan.test_models.venue.VenueInstance{:category :bar, :name "Tempest", :id 1}
(db/select-one Venue :id 1))

;; check that we can still override default-fields
(expect
Expand Down
35 changes: 18 additions & 17 deletions test/toucan/test_models/category.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,25 @@
:in maybe-lowercase-string
:out maybe-lowercase-string)

(declare assert-parent-category-exists
delete-child-categories
add-category-to-moderation-queue!
add-category-to-updated-queue!)

(models/defmodel Category :categories)

(models/defmodel Category :categories
models/IModel
(types [_]
{:name :lowercase-string})
(pre-insert [this]
(assert-parent-category-exists this))
(post-insert [this]
(add-category-to-moderation-queue! this))
(pre-update [this]
(assert-parent-category-exists this))
(post-update [this]
(add-category-to-updated-queue! this))
(pre-delete [this]
(delete-child-categories this)))

(defn- assert-parent-category-exists [{:keys [parent-category-id], :as category}]
(when parent-category-id
Expand All @@ -47,18 +63,3 @@

(defn add-category-to-updated-queue! [{:keys [id]}]
(swap! categories-recently-updated conj id))

(models/defmodel Category :categories
models/IModel
(types [_]
{:name :lowercase-string})
(pre-insert [this]
(assert-parent-category-exists this))
(post-insert [this]
(add-category-to-moderation-queue! this))
(pre-update [this]
(assert-parent-category-exists this))
(post-update [this]
(add-category-to-updated-queue! this))
(pre-delete [this]
(delete-child-categories this)))

0 comments on commit fa0ffb2

Please sign in to comment.