fix update-snippet
Created via bruno", Updated via bruno" does a cool thing",
This commit is contained in:
parent
d3babebcc4
commit
5fad04d04c
15 changed files with 90 additions and 102 deletions
10
README.md
10
README.md
|
|
@ -18,8 +18,16 @@ This project is written in [Clojure](https://clojure.org/) and data is stored in
|
|||
|
||||
### How to run dev server
|
||||
|
||||
Run the server
|
||||
|
||||
```
|
||||
$ clojure -M -m snippets.infra.api
|
||||
$ clojure -M -m snippets.main
|
||||
```
|
||||
|
||||
Hot reload:
|
||||
|
||||
```shell
|
||||
$ fd -e clj | entr -r clojure -M -m snippets.main
|
||||
```
|
||||
|
||||
### Repl
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ post {
|
|||
|
||||
body:json {
|
||||
{
|
||||
"title": "TEST from Bruno",
|
||||
"title": "Mock snippet sent via Bruno",
|
||||
"slug": "bruno-test",
|
||||
"markdown": "this is a test",
|
||||
"tags": ["test"]
|
||||
"markdown": "## MOCK SNIPPET\nCreated via bruno",
|
||||
"tags": ["mock"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ meta {
|
|||
}
|
||||
|
||||
delete {
|
||||
url: {{host}}/api/snippet?id=d77d3463-c76e-4c53-a1d5-ecaf16c6c54e
|
||||
url: {{host}}/api/snippet?slug=bruno-test
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
id: d77d3463-c76e-4c53-a1d5-ecaf16c6c54e
|
||||
slug: bruno-test
|
||||
}
|
||||
|
||||
body:json {
|
||||
|
|
|
|||
|
|
@ -5,18 +5,18 @@ meta {
|
|||
}
|
||||
|
||||
patch {
|
||||
url: {{host}}/api/snippet?id=680a3508-7709-4f71-b5c3-3dcbffe6f5cf
|
||||
url: {{host}}/api/snippet?slug=bruno-test
|
||||
body: json
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
id: 680a3508-7709-4f71-b5c3-3dcbffe6f5cf
|
||||
slug: bruno-test
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"title": "quick way to push last jj commit to git",
|
||||
"tags": ["jj", "git"]
|
||||
"title": "Mock snippet sent via Bruno with updated title",
|
||||
"markdown": "## MOCK SNIPPET\nUpdated via bruno"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
meta {
|
||||
name: get_snippet
|
||||
type: http
|
||||
seq: 6
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/api/snippet?id=aea69336-5116-49ac-ab52-bc221bdb7830
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
id: aea69336-5116-49ac-ab52-bc221bdb7830
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"title": "Test Snippet",
|
||||
"markdown": "## Cool Snippet\ndoes a cool thing",
|
||||
"tags": ["git", "jj"]
|
||||
}
|
||||
}
|
||||
|
|
@ -5,13 +5,13 @@ meta {
|
|||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/api/snippet-by-slug?slug=netcat-over-ping
|
||||
url: {{host}}/api/snippet-by-slug?slug=bruno-test
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
slug: netcat-over-ping
|
||||
slug: bruno-test
|
||||
}
|
||||
|
||||
body:json {
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ meta {
|
|||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/api/snippets?limit=25&skip=0
|
||||
url: {{host}}/api/snippets?limit=2&skip=0
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
limit: 25
|
||||
limit: 2
|
||||
skip: 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ meta {
|
|||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/api/tag?tag=git
|
||||
url: {{host}}/api/tag?tag=mock
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
params:query {
|
||||
tag: git
|
||||
tag: mock
|
||||
}
|
||||
|
||||
body:json {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
{:status 200, :body "snippet created"})
|
||||
|
||||
(defn handle-edit-snippet [{body :body-params params :query-params}]
|
||||
(let [id (get params "id")]
|
||||
(t/log! {:level :info, :data {:body body :id id}} "Received request to edit snippet")
|
||||
(let [{success :success :as res} (snippets.use-cases.edit/edit-snippet id body)]
|
||||
(let [slug (get params "slug")]
|
||||
(t/log! {:level :info, :data {:body body :slug slug}} "Received request to edit snippet")
|
||||
(let [{success :success :as res} (snippets.use-cases.edit/edit-snippet slug body)]
|
||||
(cond
|
||||
success {:status 200, :body "snippet updated"}
|
||||
(= (:reason res) :invalid-patch) {:status 400, :body "invalid patch"}
|
||||
|
|
@ -41,10 +41,13 @@
|
|||
:body (snippets.use-cases.view/view-snippets nil)}))
|
||||
|
||||
(defn handle-delete-snippet [{params :query-params}]
|
||||
(let [id (get params "id")]
|
||||
(snippets.use-cases.delete/delete-snippet id)
|
||||
(let [slug (get params "slug")
|
||||
res (snippets.use-cases.delete/delete-snippet slug)]
|
||||
(if (nil? res)
|
||||
{:status 404
|
||||
:body "No snippet with that slug found"}
|
||||
{:status 200
|
||||
:body (format "Deleted snippet with id: %s if it existed" id)}))
|
||||
:body (format "Deleted snippet with slug: %s if it existed" slug)})))
|
||||
|
||||
(defn handle-view-tags [_args]
|
||||
(let [tags (snippets.use-cases.view/view-tags)]
|
||||
|
|
@ -57,9 +60,13 @@
|
|||
:body (snippets.use-cases.view/view-snippets-by-tag tag)}))
|
||||
|
||||
(defn handle-view-snippet-by-slug [{params :query-params}]
|
||||
(let [slug (get params "slug")]
|
||||
(let [slug (get params "slug")
|
||||
snippet (snippets.use-cases.view/view-snippet-by-slug slug)]
|
||||
(if (nil? snippet)
|
||||
{:status 404
|
||||
:body "No snippet with that slug found"}
|
||||
{:status 200
|
||||
:body (snippets.use-cases.view/view-snippet-by-slug slug)}))
|
||||
:body snippet})))
|
||||
|
||||
(defn wrap [handler id]
|
||||
(fn [request]
|
||||
|
|
|
|||
|
|
@ -122,8 +122,10 @@
|
|||
db (d/db conn)
|
||||
query '[:find (pull ?e [*])
|
||||
:in $ ?slug
|
||||
:where [?e :snippet/slug ?slug]]]
|
||||
(ffirst (d/q query db slug))))
|
||||
:where [?e :snippet/slug ?slug]]
|
||||
snippet (ffirst (d/q query db slug))]
|
||||
(t/log! {:level :info, :data {:slug slug :snippet snippet}} "Got snippet by slug")
|
||||
snippet))
|
||||
|
||||
(def get-snippet-by-slug
|
||||
(wrap-snippet-return get-snippet-by-slug-from-db))
|
||||
|
|
@ -132,6 +134,7 @@
|
|||
(def update-schema
|
||||
"Malli schema for a valid update to a snippet entity."
|
||||
[:map
|
||||
[:db/id :int]
|
||||
[:snippet/title {:optional true} :string]
|
||||
[:snippet/slug {:optional true} :string]
|
||||
[:snippet/markdown {:optional true} :string]
|
||||
|
|
@ -148,17 +151,23 @@
|
|||
"Update specific fields of a snippet."
|
||||
[slug raw-patch]
|
||||
(let [conn (get-conn)
|
||||
eid (:db/id (get-snippet-by-slug slug))
|
||||
patch (to-update raw-patch)]
|
||||
(t/log! {:level :info, :data {:patch patch :slug slug}} "Patching snippet")
|
||||
db (d/db conn)
|
||||
;; query '[:find ?e
|
||||
;; :in $ ?slug
|
||||
;; :where [?e :snippet/slug ?slug]]
|
||||
;; eid (ffirst (d/q query db slug))
|
||||
eid (:db/id (get-snippet-by-slug-from-db slug))
|
||||
patch (merge (to-update raw-patch) {:db/id eid})]
|
||||
(t/log! {:level :info, :data {:patch patch :slug slug :eid eid}} "Patching snippet")
|
||||
(when (nil? eid)
|
||||
(throw (ex-info "Snippet not found" {:slug slug})))
|
||||
(when-not (m/validate update-schema patch)
|
||||
(throw (ex-info "Invalid patch" {:errors (m/explain update-schema patch) :patch patch})))
|
||||
(let [tx-data [(merge {:db/id eid} patch)]]
|
||||
(d/transact conn {:tx-data tx-data}))))
|
||||
(d/transact conn {:tx-data [patch]})))
|
||||
|
||||
(def update-snippet (wrap-snippet-return patch-snippet-in-db))
|
||||
(defn update-snippet [& args]
|
||||
(let [res (apply patch-snippet-in-db args)]
|
||||
(t/log! {:level :info, :data {:res res :args args}} "Finished patching snippet")))
|
||||
|
||||
(defn list-snippets-in-db
|
||||
"List all the snippets"
|
||||
|
|
@ -178,10 +187,10 @@
|
|||
[slug]
|
||||
(t/log! {:level :info, :data {:slug slug}} "Retracting snippet")
|
||||
(let [conn (get-conn)
|
||||
eid (:db/id (get-snippet-by-slug slug))]
|
||||
(when (nil? eid)
|
||||
(throw (ex-info "Snippet not found" {:slug slug})))
|
||||
(d/transact conn {:tx-data [[:db/retractEntity eid]]})))
|
||||
eid (:db/id (get-snippet-by-slug-from-db slug))]
|
||||
(if (nil? eid)
|
||||
nil
|
||||
(d/transact conn {:tx-data [[:db/retractEntity eid]]}))))
|
||||
|
||||
(defn list-tags
|
||||
"List all tags used in snippets with their counts."
|
||||
|
|
|
|||
15
src/snippets/use_cases/backfill_db2.clj
Normal file
15
src/snippets/use_cases/backfill_db2.clj
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
(ns snippets.use-cases.backfill-db2
|
||||
(:require
|
||||
[snippets.infra.db :as old-db]
|
||||
[snippets.infra.db2 :as new-db]
|
||||
[taoensso.telemere :as t]))
|
||||
|
||||
(defn- zdt-to-date [zdt]
|
||||
(java.util.Date/from (.toInstant zdt)))
|
||||
|
||||
(defn backfill []
|
||||
(t/log! {:level :info} "Backfilling DB2")
|
||||
(let [old-snippets (old-db/list-snippets {})
|
||||
new-snippets (map #(assoc % :pub-date (zdt-to-date (:pub-date %))) old-snippets)]
|
||||
(t/log! {:level :info :data {:count (count new-snippets)}} "Creating snippets")
|
||||
(new-db/create-snippets new-snippets)))
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
(ns snippets.use-cases.backfill-from-file
|
||||
(:require
|
||||
[clojure.java.io :as io]
|
||||
[clojure.pprint :as pprint]
|
||||
[clojure.string :as str]
|
||||
[frontmatter.core :as fm]))
|
||||
|
||||
(defn scrape-files []
|
||||
(let [dir "./old_snippets"]
|
||||
(->> (io/file dir)
|
||||
(.listFiles)
|
||||
(map #(.getName %))
|
||||
(map #(hash-map :slug (first (str/split % #"\.")) :full-path (str dir "/" %)))
|
||||
;; (map #(fm/parse (:full-path %))))))
|
||||
(map #(let [{frontmatter :frontmatter body :body} (fm/parse (:full-path %))]
|
||||
(assoc %
|
||||
:title (:title frontmatter)
|
||||
:pub-date (:date frontmatter)
|
||||
:markdown body
|
||||
:scraped true
|
||||
:tags (:snippet_types frontmatter))))
|
||||
(map #(dissoc % :full-path)))))
|
||||
|
||||
;; used repl to do backfill
|
||||
;; (doseq [s old-snippets] (xt/execute-tx db/client [[:put-docs :snippets (merge {:xt/id (:slug s)} s)]]))
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
(ns snippets.use-cases.create
|
||||
(:require
|
||||
[taoensso.telemere :as t]
|
||||
[snippets.infra.db :as db]))
|
||||
|
||||
(defn- uuid [] (str (java.util.UUID/randomUUID)))
|
||||
[snippets.infra.db2 :as db]))
|
||||
|
||||
(defn create-snippet [{:keys [title slug markdown tags]}]
|
||||
(let [id (uuid)
|
||||
pub-date (java.util.Date.)]
|
||||
(t/log! {:level :info, :data {:title title :slug slug :id id}} "Creating snippet")
|
||||
(db/put-snippet id {:title title :slug slug :markdown markdown :tags tags :pub-date pub-date})))
|
||||
(let [pub-date (java.util.Date.)]
|
||||
(t/log! {:level :info, :data {:title title :slug slug}} "Creating snippet")
|
||||
(db/create-snippets [{:title title :slug slug :markdown markdown :tags tags :pub-date pub-date}])))
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
(ns snippets.use-cases.delete
|
||||
(:require
|
||||
[snippets.infra.db :as db]
|
||||
[snippets.infra.db2 :as db]
|
||||
[taoensso.telemere :as t]))
|
||||
|
||||
(defn delete-snippet [key]
|
||||
(t/log! {:level :info, :data {:key key}} "Deleting snippet by id")
|
||||
(db/delete-snippet key))
|
||||
(defn delete-snippet [slug]
|
||||
(t/log! {:level :info, :data {:slug slug}} "Deleting snippet by slug")
|
||||
(db/delete-snippet-by-slug slug))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
(:require
|
||||
[taoensso.telemere :as t]
|
||||
[malli.core :as m]
|
||||
[snippets.infra.db :as db]))
|
||||
[snippets.infra.db2 :as db]))
|
||||
|
||||
(def valid-patch?
|
||||
(m/validator
|
||||
|
|
@ -12,11 +12,11 @@
|
|||
[:tags {:optional true} [:seqable :string]]
|
||||
[:slug {:optional true} :string]]))
|
||||
|
||||
(defn edit-snippet [id patch]
|
||||
(t/log! {:level :info, :data {:patch patch :id id}} "Editing snippet")
|
||||
(defn edit-snippet [slug patch]
|
||||
(t/log! {:level :info, :data {:patch patch :slug slug}} "Editing snippet")
|
||||
(if (valid-patch? patch)
|
||||
(do
|
||||
(t/log! {:level :info, :data {:patch patch :id id}} "Valid changes editing snippet")
|
||||
(db/patch-snippet id patch)
|
||||
(t/log! {:level :info, :data {:patch patch :slug slug}} "Valid changes editing snippet")
|
||||
(db/update-snippet slug patch)
|
||||
{:success true})
|
||||
{:success false :reason :invalid-patch}))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue