Skip to content

Commit a0bf016

Browse files
committed
feat(social): adds db for latest & top author interactions
1 parent 9236b36 commit a0bf016

File tree

8 files changed

+195
-4
lines changed

8 files changed

+195
-4
lines changed

docker/docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: "3.7"
2-
31
services:
42
db:
53
image: postgres:14

src/codes/clj/docs/backend/adapters/db/postgres.clj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
:author/avatar-url avatar-url
1313
:author/created-at created-at})
1414

15+
(defn db->author+interaction
16+
{:malli/schema [:=> [:cat [:sequential schemas.db/Author+InteractionsRow]]
17+
[:sequential schemas.model.social/Author+Interactions]]}
18+
[db-rows]
19+
(map (fn [{:keys [interactions] :as author}]
20+
(assoc (db->author author)
21+
:author/interactions interactions))
22+
db-rows))
23+
1524
(defn db->note
1625
{:malli/schema [:=> [:cat [:maybe schemas.db/Row]] [:maybe schemas.model.social/Note]]}
1726
[{:keys [id definition-id body created author-id] :as note}]
@@ -97,3 +106,15 @@
97106
[:maybe schemas.model.social/Social]]}
98107
[db-rows]
99108
(first (db->socials db-rows)))
109+
110+
(defn db->any-socials
111+
{:malli/schema [:=> [:cat [:sequential schemas.db/Row]]
112+
[:maybe [:sequential schemas.model.social/AnySocial]]]}
113+
[db-rows]
114+
(let [notes (db->notes db-rows)
115+
examples (db->examples db-rows)
116+
see-alsos (db->see-alsos db-rows)]
117+
(concat
118+
(seq notes)
119+
(seq examples)
120+
(seq see-alsos))))

src/codes/clj/docs/backend/db/postgres.clj

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,45 @@
293293
sql/format)
294294
(execute! db)
295295
adapters/db->social-definition))
296+
297+
(defn get-top-authors
298+
{:malli/schema [:=> [:cat :int schemas.types/DatabaseComponent]
299+
[:maybe [:sequential schemas.model.social/Author+Interactions]]]} ; todo out schema
300+
[limit db]
301+
(->> (-> (sql.helpers/select
302+
:author/*
303+
[[:count :social/id] :interactions])
304+
(sql.helpers/from [(sql.helpers/union-all
305+
(-> (sql.helpers/select
306+
[:note/note-id :id]
307+
[:note/author-id :author-id])
308+
(sql.helpers/from :note))
309+
(-> (sql.helpers/select
310+
[:example-edit/example-edit-id :id]
311+
[:example-edit/author-id :author-id])
312+
(sql.helpers/from :example-edit))
313+
(-> (sql.helpers/select
314+
[:see-also/see-also-id :id]
315+
[:see-also/author-id :author-id])
316+
(sql.helpers/from :see-also))) :social])
317+
(sql.helpers/join :author
318+
[:= :social/author-id :author/author-id])
319+
(sql.helpers/group-by :author/author-id)
320+
(sql.helpers/limit limit)
321+
sql/format)
322+
(execute! db)
323+
adapters/db->author+interaction))
324+
325+
(defn get-latest-interactions
326+
{:malli/schema [:=> [:cat :int schemas.types/DatabaseComponent]
327+
[:maybe [:sequential schemas.model.social/AnySocial]]]}
328+
[limit db]
329+
(->> (-> (sql.helpers/union-all
330+
get-note-query
331+
get-example-query
332+
get-see-also-query)
333+
(sql.helpers/order-by :created)
334+
(sql.helpers/limit limit)
335+
sql/format)
336+
(execute! db)
337+
adapters/db->any-socials))

src/codes/clj/docs/backend/schemas/db/postgres.clj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@
4444
:account-source
4545
:avatar-url
4646
:created-at]))
47+
48+
(def Author+InteractionsRow
49+
(mu/assoc AuthorRow :interactions :int))

src/codes/clj/docs/backend/schemas/model/social.clj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,11 @@
111111
[:social/examples [:sequential Example]]
112112
[:social/see-alsos [:sequential SeeAlso]]])
113113

114+
(def AnySocial
115+
[:or Example Note SeeAlso])
116+
114117
(def Author+Socials
115118
(mu/assoc Author [:author/socials {:optional true}] [:sequential Social]))
119+
120+
(def Author+Interactions
121+
(mu/assoc Author [:author/interactions {:optional true}] :int))

test/integration/codes/clj/docs/backend/db/postgres_test.clj

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[com.stuartsierra.component :as component]
55
[integration.codes.clj.docs.backend.util :as util]
66
[integration.codes.clj.docs.backend.util.db.postgres :as util.db.postgres]
7+
[matcher-combinators.matchers :as m]
78
[parenthesin.components.config.aero :as components.config]
89
[parenthesin.components.db.jdbc-hikari :as components.database]
910
[parenthesin.helpers.malli :as helpers.malli]
@@ -71,7 +72,33 @@
7172
:example/author-id)]
7273
:social/see-alsos [see-also-1]}]}
7374

74-
(db/get-author+socials "delboni" "github" database))))
75+
(db/get-author+socials "delboni" "github" database)))
76+
77+
(flow "check latest top authors in db"
78+
(match? (m/in-any-order
79+
[#:author{:author-id uuid?
80+
:login "not-delboni"
81+
:account-source "github"
82+
:avatar-url "https://my.pic.com/me.jpg"
83+
:created-at inst?
84+
:interactions 3}
85+
#:author{:author-id uuid?
86+
:login "delboni"
87+
:account-source "github"
88+
:avatar-url "https://my.pic.com/me2.jpg"
89+
:created-at inst?
90+
:interactions 3}])
91+
(util.db.postgres/get-top-authors 10)))
92+
93+
(flow "check latest social interactions in db"
94+
(match? (m/in-any-order
95+
[#:note{:note-id uuid?}
96+
#:note{:note-id uuid?}
97+
#:example{:example-id uuid?}
98+
#:example{:example-id uuid?}
99+
#:see-also{:see-also-id uuid?}
100+
#:see-also{:see-also-id uuid?}])
101+
(util.db.postgres/get-latest-interactions 10))))
75102

76103
(defflow see-also-db-test
77104
{:init (util/start-system! create-and-start-components!)

test/integration/codes/clj/docs/backend/util/db/postgres.clj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,19 @@
108108
(->> database
109109
(db/get-by-definition definition-id)
110110
state-flow.api/return)))
111+
112+
(defn get-top-authors
113+
[limit]
114+
(flow "get top authors with their interactions sum"
115+
[database (state-flow.api/get-state :database)]
116+
(->> database
117+
(db/get-top-authors limit)
118+
state-flow.api/return)))
119+
120+
(defn get-latest-interactions
121+
[limit]
122+
(flow "get latest social interactions"
123+
[database (state-flow.api/get-state :database)]
124+
(->> database
125+
(db/get-latest-interactions limit)
126+
state-flow.api/return)))

test/unit/codes/clj/docs/backend/adapters/db/postgres_test.clj

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
(properties/for-all [row (mg/generator schemas.db.postgres/AuthorRow)]
1818
(m/validate schemas.model.social/Author (adapters/db->author row))))
1919

20+
(defspec db->author+interaction-test 50
21+
(properties/for-all [row (mg/generator [:sequential schemas.db.postgres/Author+InteractionsRow])]
22+
(m/validate [:sequential schemas.model.social/Author+Interactions] (adapters/db->author+interaction row))))
23+
2024
(defspec db->note-test 50
2125
(properties/for-all [row (mg/generator (mu/assoc schemas.db.postgres/FullRow :type [:enum "note"]))]
2226
(m/validate schemas.model.social/Note (adapters/db->note row))))
@@ -255,4 +259,78 @@
255259
:created-at #inst "2020-10-23T00:00:00.000-00:00"
256260
:definition-id "clojure.core/disj2"}])))))
257261

258-
262+
(deftest db->any-socials-test
263+
(testing "should list of any social parsed in db-rows"
264+
(is (match? [#:note{:note-id #uuid "d9564b50-98f8-4c04-a668-bd24c1241e34"
265+
:definition-id "clojure.core/disj"
266+
:body "my note about this function."
267+
:created-at #inst "2020-10-23T00:00:00.000-00:00"
268+
:author #:author{:author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
269+
:login "delboni"
270+
:account-source "github"
271+
:avatar-url "https://my.pic.com/me.jpg"
272+
:created-at #inst "2020-10-23T00:00:00.000-00:00"}}
273+
#:note{:note-id #uuid "7aac759f-35dc-456c-9611-44589336560c"
274+
:definition-id "clojure.core/disj"
275+
:body "my second note about this function."
276+
:created-at #inst "2020-10-23T00:00:00.000-00:00"
277+
:author #:author{:author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
278+
:login "delboni"
279+
:account-source "github"
280+
:avatar-url "https://my.pic.com/me.jpg"
281+
:created-at #inst "2020-10-23T00:00:00.000-00:00"}}
282+
#:example{:example-id #uuid "0f0a0fe8-7147-4d45-b212-3a32bc37d07a"
283+
:definition-id "clojure.core/disj"
284+
:body "my example about this function. edited again"
285+
:created-at #inst "2020-10-23T03:00:00.000-00:00"
286+
:author #:author{:author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
287+
:login "delboni"
288+
:account-source "github"
289+
:avatar-url "https://my.pic.com/me.jpg"
290+
:created-at #inst "2020-10-23T00:00:00.000-00:00"}
291+
:editors
292+
[{:author/author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
293+
:author/login "delboni"
294+
:author/account-source "github"
295+
:author/avatar-url "https://my.pic.com/me.jpg"
296+
:author/created-at #inst "2020-10-23T00:00:00.000-00:00"
297+
:editor/edited-at #inst "2020-10-23T01:00:00.000-00:00"}
298+
{:author/author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
299+
:author/login "delboni"
300+
:author/account-source "github"
301+
:author/avatar-url "https://my.pic.com/me.jpg"
302+
:author/created-at #inst "2020-10-23T00:00:00.000-00:00"
303+
:editor/edited-at #inst "2020-10-23T02:00:00.000-00:00"}
304+
{:author/author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
305+
:author/login "delboni"
306+
:author/account-source "github"
307+
:author/avatar-url "https://my.pic.com/me.jpg"
308+
:author/created-at #inst "2020-10-23T00:00:00.000-00:00"
309+
:editor/edited-at #inst "2020-10-23T03:00:00.000-00:00"}]}
310+
#:example{:example-id #uuid "c9df4a18-ec91-4d3f-9cb2-d65d48db88eb"
311+
:definition-id "clojure.core/disj"
312+
:body "another example about this function."
313+
:created-at #inst "2020-10-23T00:00:00.000-00:00"
314+
:author #:author{:author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
315+
:login "delboni"
316+
:account-source "github"
317+
:avatar-url "https://my.pic.com/me.jpg"
318+
:created-at #inst "2020-10-23T00:00:00.000-00:00"}
319+
:editors
320+
[{:author/author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
321+
:author/login "delboni"
322+
:author/account-source "github"
323+
:author/avatar-url "https://my.pic.com/me.jpg"
324+
:author/created-at #inst "2020-10-23T00:00:00.000-00:00"
325+
:editor/edited-at #inst "2020-10-23T00:00:00.000-00:00"}]}
326+
#:see-also{:see-also-id #uuid "b8a824b9-6a3a-4a10-a318-58313637ecb6"
327+
:definition-id "clojure.core/disj"
328+
:definition-id-to "clojure.core/dissoc"
329+
:created-at #inst "2020-10-23T00:00:00.000-00:00"
330+
:author #:author{:author-id #uuid "387863e6-e32b-4d4b-8ec5-8cf4dab7e048"
331+
:login "delboni"
332+
:account-source "github"
333+
:avatar-url "https://my.pic.com/me.jpg"
334+
:created-at
335+
#inst "2020-10-23T00:00:00.000-00:00"}}]
336+
(adapters/db->any-socials db-rows)))))

0 commit comments

Comments
 (0)