♻️ Restructure the services directory.

This commit is contained in:
Andrey Antukh 2019-12-01 16:48:41 +01:00
parent eeb5482d36
commit b66bc02098
45 changed files with 951 additions and 960 deletions

View file

@ -0,0 +1,69 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.icons
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.db :as db]
[uxbox.services.queries :as sq]
[uxbox.util.blob :as blob]
[uxbox.util.exceptions :as ex]
[uxbox.util.spec :as us]))
;; --- Helpers & Specs
(s/def ::id ::us/uuid)
(s/def ::user ::us/uuid)
(s/def ::collection-id (s/nilable ::us/uuid))
(defn decode-icon-row
[{:keys [metadata] :as row}]
(when row
(cond-> row
metadata (assoc :metadata (blob/decode metadata)))))
;; --- Query: Collections
(def ^:private icons-collections-sql
"select *,
(select count(*) from icons where collection_id = ic.id) as num_icons
from icons_collections as ic
where (ic.user_id = $1 or
ic.user_id = '00000000-0000-0000-0000-000000000000'::uuid)
and ic.deleted_at is null
order by ic.created_at desc")
(s/def ::icons-collections
(s/keys :req-un [::user]))
(sq/defquery ::icons-collections
[{:keys [user] :as params}]
(let [sqlv [icons-collections-sql user]]
(db/query db/pool sqlv)))
;; --- Icons By Collection ID
(def ^:private icons-by-collection-sql
"select *
from icons as i
where (i.user_id = $1 or
i.user_id = '00000000-0000-0000-0000-000000000000'::uuid)
and i.deleted_at is null
and case when $2::uuid is null then i.collection_id is null
else i.collection_id = $2::uuid
end
order by i.created_at desc")
(s/def ::icons-by-collection
(s/keys :req-un [::user]
:opt-un [::collection-id]))
(sq/defquery ::icons-by-collection
[{:keys [user collection-id] :as params}]
(let [sqlv [icons-by-collection-sql user collection-id]]
(-> (db/query db/pool sqlv)
(p/then' #(mapv decode-icon-row %)))))

View file

@ -0,0 +1,109 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.images
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[promesa.exec :as px]
[uxbox.db :as db]
[uxbox.media :as media]
[uxbox.images :as images]
[uxbox.services.queries :as sq]
[uxbox.services.util :as su]
[uxbox.util.blob :as blob]
[uxbox.util.data :as data]
[uxbox.util.exceptions :as ex]
[uxbox.util.spec :as us]
[uxbox.util.uuid :as uuid]
[vertx.core :as vc]))
(def +thumbnail-options+
{:src :path
:dst :thumbnail
:width 300
:height 100
:quality 92
:format "webp"})
(defn populate-thumbnail
[row]
(let [opts +thumbnail-options+]
(-> (px/submit! #(images/populate-thumbnails row opts))
(su/handle-on-context))))
(defn populate-thumbnails
[rows]
(if (empty? rows)
rows
(p/all (map populate-thumbnail rows))))
(defn populate-urls
[row]
(images/populate-urls row media/images-storage :path :url))
(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::user ::us/uuid)
(s/def ::collection-id (s/nilable ::us/uuid))
(def ^:private images-collections-sql
"select *,
(select count(*) from images where collection_id = ic.id) as num_images
from images_collections as ic
where (ic.user_id = $1 or
ic.user_id = '00000000-0000-0000-0000-000000000000'::uuid)
and ic.deleted_at is null
order by ic.created_at desc;")
(s/def ::images-collections
(s/keys :req-un [::user]))
(sq/defquery ::images-collections
[{:keys [user] :as params}]
(db/query db/pool [images-collections-sql user]))
;; --- Retrieve Image
(defn retrieve-image
[conn id]
(let [sql "select * from images
where id = $1
and deleted_at is null;"]
(db/query-one conn [sql id])))
;; (s/def ::retrieve-image
;; (s/keys :req-un [::user ::us/id]))
;; (defmethod core/query :retrieve-image
;; [params]
;; (s/assert ::retrieve-image params)
;; (with-open [conn (db/connection)]
;; (retrieve-image conn params)))
;; --- Query Images by Collection (id)
(def images-by-collection-sql
"select * from images
where (user_id = $1 or
user_id = '00000000-0000-0000-0000-000000000000'::uuid)
and deleted_at is null
and case when $2::uuid is null then collection_id is null
else collection_id = $2::uuid
end
order by created_at desc;")
(s/def ::images-by-collection-query
(s/keys :req-un [::user]
:opt-un [::collection-id]))
(sq/defquery ::images-by-collection
[{:keys [user collection-id] :as params}]
(let [sqlv [images-by-collection-sql user collection-id]]
(-> (db/query db/pool sqlv)
(p/then populate-thumbnails)
(p/then #(mapv populate-urls %)))))

View file

@ -0,0 +1,92 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.pages
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.db :as db]
[uxbox.services.queries :as sq]
[uxbox.util.blob :as blob]
[uxbox.util.spec :as us]
[uxbox.util.sql :as sql]))
;; --- Helpers & Specs
(declare decode-row)
(s/def ::id ::us/uuid)
(s/def ::user ::us/uuid)
(s/def ::project-id ::us/uuid)
;; --- Query: Pages by Project
(s/def ::pages-by-project
(s/keys :req-un [::user ::project-id]))
(sq/defquery ::pages-by-project
[{:keys [user project-id] :as params}]
(let [sql "select pg.*,
pg.data,
pg.metadata
from pages as pg
where pg.user_id = $2
and pg.project_id = $1
and pg.deleted_at is null
order by pg.created_at asc;"]
(-> (db/query db/pool [sql project-id user])
(p/then #(mapv decode-row %)))))
;; --- Query: Page by Id
(s/def ::page
(s/keys :req-un [::user ::id]))
(sq/defquery ::page
[{:keys [user id] :as params}]
(let [sql "select pg.*,
pg.data,
pg.metadata
from pages as pg
where pg.user_id = $2
and pg.id = $1
and pg.deleted_at is null"]
(-> (db/query-one db/pool [sql id user])
(p/then' decode-row))))
;; --- Query: Page History
(s/def ::page-id ::us/uuid)
(s/def ::max ::us/integer)
(s/def ::pinned ::us/boolean)
(s/def ::since ::us/integer)
(s/def ::page-history
(s/keys :req-un [::page-id ::user]
:opt-un [::max ::pinned ::since]))
(sq/defquery ::page-history
[{:keys [page-id user since max pinned] :or {since Long/MAX_VALUE max 10}}]
(let [sql (-> (sql/from ["pages_history" "ph"])
(sql/select "ph.*")
(sql/where ["ph.user_id = ?" user]
["ph.page_id = ?" page-id]
["ph.version < ?" since]
(when pinned
["ph.pinned = ?" true]))
(sql/order "ph.version desc")
(sql/limit max))]
(-> (db/query db/pool (sql/fmt sql))
(p/then (partial mapv decode-row)))))
;; --- Helpers
(defn decode-row
[{:keys [data metadata] :as row}]
(when row
(cond-> row
data (assoc :data (blob/decode data))
metadata (assoc :metadata (blob/decode metadata)))))

View file

@ -0,0 +1,73 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.profiles
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[promesa.exec :as px]
[uxbox.db :as db]
[uxbox.images :as images]
[uxbox.services.queries :as sq]
[uxbox.services.util :as su]
[uxbox.util.blob :as blob]
[uxbox.util.spec :as us]))
;; --- Helpers & Specs
(declare decode-profile-row)
(declare strip-private-attrs)
(s/def ::email ::us/email)
(s/def ::fullname ::us/string)
(s/def ::metadata any?)
(s/def ::old-password ::us/string)
(s/def ::password ::us/string)
(s/def ::path ::us/string)
(s/def ::user ::us/uuid)
(s/def ::username ::us/string)
;; --- Query: Profile (own)
(defn resolve-thumbnail
[user]
(let [opts {:src :photo
:dst :photo
:size [100 100]
:quality 90
:format "jpg"}]
(-> (px/submit! #(images/populate-thumbnails user opts))
(su/handle-on-context))))
(defn get-profile
[conn id]
(let [sql "select * from users where id=$1 and deleted_at is null"]
(-> (db/query-one db/pool [sql id])
(p/then' decode-profile-row))))
(s/def ::profile
(s/keys :req-un [::user]))
(sq/defquery :profile
{:doc "Retrieve the user profile."
:spec ::profile}
[{:keys [user] :as params}]
(-> (get-profile db/pool user)
(p/then' strip-private-attrs)))
;; --- Attrs Helpers
(defn decode-profile-row
[{:keys [metadata] :as row}]
(when row
(cond-> row
metadata (assoc :metadata (blob/decode metadata)))))
(defn strip-private-attrs
"Only selects a publicy visible user attrs."
[profile]
(select-keys profile [:id :username :fullname :metadata
:email :created-at :photo]))

View file

@ -0,0 +1,48 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.projects
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.db :as db]
[uxbox.services.queries :as sq]
[uxbox.util.blob :as blob]
[uxbox.util.spec :as us]))
;; --- Helpers & Specs
(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::token ::us/string)
(s/def ::user ::us/uuid)
;; --- Query: Projects
(def ^:private projects-sql
"select distinct on (p.id, p.created_at)
p.*,
array_agg(pg.id) over (
partition by p.id
order by pg.created_at
range between unbounded preceding and unbounded following
) as pages
from projects as p
left join pages as pg
on (pg.project_id = p.id)
where p.user_id = $1
order by p.created_at asc")
(s/def ::projects-query
(s/keys :req-un [::user]))
(sq/defquery :projects
{:doc "Query all projects"
:spec ::projects-query}
[{:keys [user] :as params}]
(-> (db/query db/pool [projects-sql user])
(p/then (fn [rows]
(mapv #(update % :pages vec) rows)))))

View file

@ -0,0 +1,34 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.user-storage
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.db :as db]
[uxbox.services.queries :as sq]
[uxbox.services.util :as su]
[uxbox.util.blob :as blob]
[uxbox.util.spec :as us]))
(defn decode-row
[{:keys [val] :as row}]
(when row
(cond-> row
val (assoc :val (blob/decode val)))))
(s/def ::user-storage-item
(s/keys :req-un [::key ::user]))
(sq/defquery ::user-storage-entry
[{:keys [key user]}]
(let [sql "select kv.*
from user_storage as kv
where kv.user_id = $2
and kv.key = $1"]
(-> (db/query-one db/pool [sql key user])
(p/then' su/raise-not-found-if-nil)
(p/then' decode-row))))