(ns repl (:require [clojure.java.io :as io] [com.biffweb :as biff] [com.biffweb.my-project :as main] [com.biffweb.my-project.util.db :as db] [honey.sql :as sql] [honey.sql.helpers :refer [drop-table]] [migratus.core :as migratus] [next.jdbc :as jdbc])) ;; REPL-driven development ;; ---------------------------------------------------------------------------------------- ;; If you're new to REPL-driven development, Biff makes it easy to get started: whenever ;; you save a file, your changes will be evaluated. Biff is structured so that in most ;; cases, that's all you'll need to do for your changes to take effect. (See main/refresh ;; below for more details.) ;; ;; The `clj -M:dev dev` command also starts an nREPL server on port 7888, so if you're ;; already familiar with REPL-driven development, you can connect to that with your editor. ;; ;; If you're used to jacking in with your editor first and then starting your app via the ;; REPL, you will need to instead connect your editor to the nREPL server that `clj -M:dev ;; dev` starts. e.g. if you use emacs, instead of running `cider-jack-in`, you would run ;; `cider-connect`. See "Connecting to a Running nREPL Server:" ;; https://docs.cider.mx/cider/basics/up_and_running.html#connect-to-a-running-nrepl-server ;; ---------------------------------------------------------------------------------------- ;; This function should only be used from the REPL. Regular application code ;; should receive the system map from the parent Biff component. For example, ;; the use-jetty component merges the system map into incoming Ring requests. (defn get-context [] (biff/merge-context @main/system)) (defn add-fixtures [] (let [{:keys [example/ds] :as _ctx} (get-context)] (jdbc/execute! ds (db/new-user-statement "a@example.com")))) (defn reset-db! [] (let [{:keys [example/ds]} (get-context) tables [:users :auth_code] drop-statements (map (fn [table] (sql/format (drop-table :if-exists table))) tables)] (db/execute-all! ds drop-statements) (jdbc/execute! ds [(slurp (io/resource "migrations.sql"))]))) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn new-migration [migration-name] (migratus/create (com.biffweb.my-project/ctx->migratus-config (get-context)) migration-name)) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn check-config [] (let [prod-config (biff/use-aero-config {:biff.config/profile "prod"}) dev-config (biff/use-aero-config {:biff.config/profile "dev"}) ;; Add keys for any other secrets you've added to resources/config.edn secret-keys [:biff.middleware/cookie-secret :biff/jwt-secret :postmark/api-key] get-secrets (fn [{:keys [biff/secret] :as _config}] (into {} (map (fn [k] [k (secret k)])) secret-keys))] {:prod-config prod-config :dev-config dev-config :prod-secrets (get-secrets prod-config) :dev-secrets (get-secrets dev-config)})) (comment ;; Call this function if you make a change to main/initial-system, ;; main/components, :tasks, :queues, config.env, or deps.edn. (main/refresh) ;; Call this in dev if you'd like to add some seed data to your database. If ;; you edit the seed data, you can reset the database by calling reset-db! ;; (DON'T do that in prod) and calling add-fixtures again. (reset-db!) (add-fixtures) ;; Create a user (let [{:keys [example/ds] :as _ctx} (get-context)] (jdbc/execute! ds (db/new-user-statement "hello@example.com"))) ;; Query the database (let [{:keys [example/ds] :as _ctx} (get-context)] (jdbc/execute! ds (sql/format {:select :* :from :users}))) ;; Update an existing user's email address (let [{:keys [example/ds] :as _ctx} (get-context)] (jdbc/execute! ds (sql/format {:update :users :set {:email "new.address@example.com"} :where [:= :email "hello@example.com"]}))) (sort (keys (get-context))) ;; Check the terminal for output. (biff/submit-job (get-context) :echo {:foo "bar"}) (deref (biff/submit-job-for-result (get-context) :echo {:foo "bar"})))