@@ -15,59 +15,7 @@
15{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
15{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
18−module Data.Query (
18+module Data.Query where
33− getAnonymousChannelPosts,
37− ResponseWithUsers(..),
40− getMessagesInUserChat,
41− getMessagesInGroupChat,
69− groupChatIsValidForUser
72import Squeal.PostgreSQL
20import Squeal.PostgreSQL
73import Data.User
21import Data.User
@@ -110,6 +58,9 @@ import qualified Data.Vector as V
110import Server.Auth.Token
58import Server.Auth.Token
111import Server.Error
59import Server.Error
112import Data.Text.Validator
60import Data.Text.Validator
61+import Control.Monad.Except
62+import Control.Monad.IO.Class
63+import Crypto.Hash.SHA512 (hash)
114-- MARK: Documentation
65-- MARK: Documentation
@@ -122,14 +73,17 @@ instance (ToSample r) => ToSample (ResponseWithUsers r) where
122type TableEndo schema params from grouping = TableExpression schema params from grouping ->
73type TableEndo schema params from grouping = TableExpression schema params from grouping ->
123 TableExpression schema params from grouping
74 TableExpression schema params from grouping
76+-- |Функция, возвращаяющая запрос на посты, прменяя к нему данный ндоморфизм.
125postsQ :: TableEndo Schema params _ 'Ungrouped -> Query Schema params _
77postsQ :: TableEndo Schema params _ 'Ungrouped -> Query Schema params _
126postsQ te = selectStar $ te (from $ table #posts)
78postsQ te = selectStar $ te (from $ table #posts)
80+-- |Функция, возвращающая посты
128postViewT :: TableEndo Schema params _ 'Ungrouped -> TableExpression Schema params _ 'Ungrouped
81postViewT :: TableEndo Schema params _ 'Ungrouped -> TableExpression Schema params _ 'Ungrouped
129postViewT te = from $ subquery (postsQ te `As` #posts) &
82postViewT te = from $ subquery (postsQ te `As` #posts) &
130 innerJoin (table #postElements)
83 innerJoin (table #postElements)
131 (#posts ! #postRowId .== #postElements ! #rowElementId)
84 (#posts ! #postRowId .== #postElements ! #rowElementId)
86+-- |Функция, возвращающая запрос на поста, примення два промежуточных эндоморфизма к таблице.
134 :: TableEndo Schema params _ 'Ungrouped
88 :: TableEndo Schema params _ 'Ungrouped
135 -- ^ PostRowResponse endo
89 -- ^ PostRowResponse endo
@@ -172,6 +126,7 @@ getPostQ oTe te = select (
172-- let rows = M.fromList $ map (tupleBy $ quoteRowId . head) . groupBy ((==) `on` quoteRowId) . sortBy (compare `on` quoteRowId) $ rows'
126-- let rows = M.fromList $ map (tupleBy $ quoteRowId . head) . groupBy ((==) `on` quoteRowId) . sortBy (compare `on` quoteRowId) $ rows'
173-- return $ M.lookup qId rows >>= rowsToQuote rows
127-- return $ M.lookup qId rows >>= rowsToQuote rows
129+-- |Запрос, возвращающий пользователя по адресу почты.
175getUserWithEmailQ :: Query Schema (TuplePG (Only UserEmail)) (RowPG (User FacultyUrl))
130getUserWithEmailQ :: Query Schema (TuplePG (Only UserEmail)) (RowPG (User FacultyUrl))
176getUserWithEmailQ = select (
131getUserWithEmailQ = select (
177 #userRowId `as` #userId :*
132 #userRowId `as` #userId :*
@@ -184,6 +139,7 @@ getUserWithEmailQ = select (
184 where_ (#userRowEmail .== param @1) &
139 where_ (#userRowEmail .== param @1) &
185 where_ (notNull #userRowIsValidated))
140 where_ (notNull #userRowIsValidated))
142+-- |Запрос, возвращающий подтвержденных пользователей.
187verifiedUserIdsQ :: [UserId] -> Maybe (Query Schema '[] (RowPG (Only UserId)))
143verifiedUserIdsQ :: [UserId] -> Maybe (Query Schema '[] (RowPG (Only UserId)))
188verifiedUserIdsQ uIds = case idsToColumn uIds of
144verifiedUserIdsQ uIds = case idsToColumn uIds of
189 Just idQ -> Just $ select (#users ! #userRowId `as` #fromOnly) $ from (subquery (idQ `As` #ids) &
145 Just idQ -> Just $ select (#users ! #userRowId `as` #fromOnly) $ from (subquery (idQ `As` #ids) &
@@ -191,6 +147,7 @@ verifiedUserIdsQ uIds = case idsToColumn uIds of
191 (#ids ! #id .== #users ! #userRowId))
147 (#ids ! #id .== #users ! #userRowId))
192 Nothing -> Nothing
148 Nothing -> Nothing
150+-- |Запрос, возвращающий пользователей с данными идентификаторами.
194getUsersQ :: [UserId] -> Maybe (Query Schema '[] (RowPG UserRow))
151getUsersQ :: [UserId] -> Maybe (Query Schema '[] (RowPG UserRow))
195getUsersQ uIds = case idsToColumn uIds of
152getUsersQ uIds = case idsToColumn uIds of
196 Just idQ -> Just $ select (
153 Just idQ -> Just $ select (
@@ -216,6 +173,7 @@ getUsersQ uIds = case idsToColumn uIds of
216 where_ (notNull $ #users ! #userRowIsValidated))
173 where_ (notNull $ #users ! #userRowIsValidated))
217 Nothing -> Nothing
174 Nothing -> Nothing
176+-- |Запорс, возвращающий всех пользователей.
219getAllUsersQ :: Query Schema '[] (RowPG UserRow)
177getAllUsersQ :: Query Schema '[] (RowPG UserRow)
220getAllUsersQ = select (
178getAllUsersQ = select (
221 #users ! #userRowId :*
179 #users ! #userRowId :*
@@ -237,6 +195,7 @@ getAllUsersQ = select (
237 (#users ! #userRowFacultyUrl .== #faculties ! #facultyUrl))&
195 (#users ! #userRowFacultyUrl .== #faculties ! #facultyUrl))&
238 where_ (notNull $ #users ! #userRowIsValidated))
196 where_ (notNull $ #users ! #userRowIsValidated))
198+-- |Запрос, возвращающий все посты по идентификатору.
240getPostsByIdQ :: [PostId] -> Maybe (Query Schema '[] (RowPG PostRowResponse))
199getPostsByIdQ :: [PostId] -> Maybe (Query Schema '[] (RowPG PostRowResponse))
241getPostsByIdQ pIds = case idsToColumn pIds of
200getPostsByIdQ pIds = case idsToColumn pIds of
242 Just idQ -> Just $ selectDotStar #posts $ from (subquery (idQ `As` #ids) &
201 Just idQ -> Just $ selectDotStar #posts $ from (subquery (idQ `As` #ids) &
@@ -245,14 +204,17 @@ getPostsByIdQ pIds = case idsToColumn pIds of
245 (#ids ! #id .== #posts ! #postRowId))
204 (#ids ! #id .== #posts ! #postRowId))
246 Nothing -> Nothing
205 Nothing -> Nothing
248type Limit = Word64
208type Limit = Word64
210+-- |SQL оператор IS NOT FALSE
250isNotFalse
211isNotFalse
251 :: Expression schema from grouping params ('Null ty)
212 :: Expression schema from grouping params ('Null ty)
252 -- ^ possibly @NULL@
213 -- ^ possibly @NULL@
253 -> Condition schema from grouping params
214 -> Condition schema from grouping params
254isNotFalse x = UnsafeExpression $ renderExpression x <+> "IS NOT FALSE"
215isNotFalse x = UnsafeExpression $ renderExpression x <+> "IS NOT FALSE"
217+-- |Запрос, возвращающий последние посты.
256getLastPostsQ
218getLastPostsQ
257 :: TableEndo _ _ _ _
219 :: TableEndo _ _ _ _
@@ -267,12 +229,14 @@ getLastPostsQ te lim dir = getPostQ
268 ((.^), order) = directionToOperator dir
230 ((.^), order) = directionToOperator dir
232+-- |Запрос, возвращающий последние посты для данного пользователя.
270getLastNPostsForUserQ
233getLastNPostsForUserQ
272 -> P.PaginationDirection
235 -> P.PaginationDirection
273 -> Query Schema (TuplePG (Maybe PostId, UserId)) (RowPG PostRowResponse)
236 -> Query Schema (TuplePG (Maybe PostId, UserId)) (RowPG PostRowResponse)
274getLastNPostsForUserQ = getLastPostsQ $ where_ (#posts ! #postRowAuthorId .== param @2)
237getLastNPostsForUserQ = getLastPostsQ $ where_ (#posts ! #postRowAuthorId .== param @2)
239+-- |Запрос на создание поста.
276createPostRowQ :: Manipulation Schema (TuplePG (UserId, Vector Text)) (RowPG (Only PostId))
240createPostRowQ :: Manipulation Schema (TuplePG (UserId, Vector Text)) (RowPG (Only PostId))
277createPostRowQ = insertRow #posts
241createPostRowQ = insertRow #posts
278 (Default `as` #postRowId :*
242 (Default `as` #postRowId :*
@@ -282,6 +246,7 @@ createPostRowQ = insertRow #posts
282 OnConflictDoRaise
246 OnConflictDoRaise
283 (Returning $ #postRowId `as` #fromOnly)
247 (Returning $ #postRowId `as` #fromOnly)
249+-- |Запрос на создание элементов постов.
285createPostElementRowsQ :: Manipulation Schema (TuplePG (PostElementRow Post)) '[]
250createPostElementRowsQ :: Manipulation Schema (TuplePG (PostElementRow Post)) '[]
286createPostElementRowsQ = insertRow_ #postElements
251createPostElementRowsQ = insertRow_ #postElements
287 (Set (param @1) `as` #rowElementId :*
252 (Set (param @1) `as` #rowElementId :*
@@ -292,11 +257,13 @@ createPostElementRowsQ = insertRow_ #postElements
292 Set (param @6) `as` #rowElementQuote :*
257 Set (param @6) `as` #rowElementQuote :*
293 Set (param @7) `as` #rowElementAttachment)
258 Set (param @7) `as` #rowElementAttachment)
260+-- |Запрос, возвращающий канал для данного пользователя.
295getChannelForUserQ :: Query Schema (TuplePG (UserId, NamedChannelId)) (RowPG NamedChannelFull)
261getChannelForUserQ :: Query Schema (TuplePG (UserId, NamedChannelId)) (RowPG NamedChannelFull)
296getChannelForUserQ = selectStar $
262getChannelForUserQ = selectStar $
297 from (table #channels) &
263 from (table #channels) &
298 where_ (#namedChannelFullOwner .== param @1 .&& #namedChannelFullId .== param @2)
264 where_ (#namedChannelFullOwner .== param @1 .&& #namedChannelFullId .== param @2)
266+-- |Запрос, обновляющий данные о пользователе.
300updateUserQ :: Manipulation Schema (TuplePG (UserUpdateRow)) (RowPG (Only UserId))
267updateUserQ :: Manipulation Schema (TuplePG (UserUpdateRow)) (RowPG (Only UserId))
301updateUserQ = update #users (
268updateUserQ = update #users (
302 Same `as` #userRowId :*
269 Same `as` #userRowId :*
@@ -309,12 +276,14 @@ updateUserQ = update #users (
309 (#userRowId .== param @1)
276 (#userRowId .== param @1)
310 (Returning $ #userRowId `as` #fromOnly)
277 (Returning $ #userRowId `as` #fromOnly)
279+-- |Запрос, возвращающий каналы пользователя.
312getAllChannelsForUserQ :: Query Schema (TuplePG (Only UserId)) (RowPG NamedChannelFull)
280getAllChannelsForUserQ :: Query Schema (TuplePG (Only UserId)) (RowPG NamedChannelFull)
313getAllChannelsForUserQ = selectStar $
281getAllChannelsForUserQ = selectStar $
314 from (table #channels) &
282 from (table #channels) &
315 where_ (#namedChannelFullOwner .== param @1) &
283 where_ (#namedChannelFullOwner .== param @1) &
316 orderBy [#namedChannelFullId & Desc]
284 orderBy [#namedChannelFullId & Desc]
286+-- |Запрос, осуществляющий поиск по каналам данного пользователя.
318searchChannelsForUserQ :: Query Schema (TuplePG (UserId, Text)) (RowPG NamedChannelFull)
287searchChannelsForUserQ :: Query Schema (TuplePG (UserId, Text)) (RowPG NamedChannelFull)
319searchChannelsForUserQ = selectStar $
288searchChannelsForUserQ = selectStar $
320 from (table #channels) &
289 from (table #channels) &
@@ -331,6 +300,7 @@ searchChannelsForUserQ = selectStar $
331 vector1 = tsVector' #namedChannelFullName
300 vector1 = tsVector' #namedChannelFullName
332 query = tsQuery' (param @2)
301 query = tsQuery' (param @2)
303+-- |Запрос, обновляющий факультет.
334updateFacultyQ :: Manipulation Schema (TuplePG Faculty) '[]
304updateFacultyQ :: Manipulation Schema (TuplePG Faculty) '[]
335updateFacultyQ = insertRow #faculties
305updateFacultyQ = insertRow #faculties
@@ -345,10 +315,12 @@ updateFacultyQ = insertRow #faculties
345 (OnConflictDoNothing)
315 (OnConflictDoNothing)
346 (Returning Nil)
316 (Returning Nil)
318+-- |Запрос, возвращающий факультет.
348getFacultyQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
319getFacultyQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
349getFacultyQ = selectStar (from (table #faculties) &
320getFacultyQ = selectStar (from (table #faculties) &
350 where_ (#facultyUrl .== param @1))
321 where_ (#facultyUrl .== param @1))
323+-- |Запрос на создание нового именованного канала.
352createNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelCreation) (RowPG (Only NamedChannelId))
324createNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelCreation) (RowPG (Only NamedChannelId))
353createNamedChannelQ = insertRow #channels
325createNamedChannelQ = insertRow #channels
@@ -361,14 +333,17 @@ createNamedChannelQ = insertRow #channels
361 OnConflictDoRaise
333 OnConflictDoRaise
362 (Returning $ #namedChannelFullId `as` #fromOnly)
334 (Returning $ #namedChannelFullId `as` #fromOnly)
336+-- |Запрос, возвращающий количество каналов у данного пользователя.
364countChannelsQ :: Query Schema (TuplePG (Only UserId)) (RowPG (Only Int64))
337countChannelsQ :: Query Schema (TuplePG (Only UserId)) (RowPG (Only Int64))
365countChannelsQ = select (countStar `as` #fromOnly) (from (table #channels) &
338countChannelsQ = select (countStar `as` #fromOnly) (from (table #channels) &
366 where_ (#namedChannelFullOwner .== param @1) &
339 where_ (#namedChannelFullOwner .== param @1) &
367 groupBy #namedChannelFullOwner)
340 groupBy #namedChannelFullOwner)
342+-- |Запрос, удаляющий канал у данного пользователя.
369deleteNamedChannelQ :: Manipulation Schema (TuplePG (Only NamedChannelId)) '[]
343deleteNamedChannelQ :: Manipulation Schema (TuplePG (Only NamedChannelId)) '[]
370deleteNamedChannelQ = deleteFrom_ #channels (#namedChannelFullId .== param @1)
344deleteNamedChannelQ = deleteFrom_ #channels (#namedChannelFullId .== param @1)
346+-- |Запрос, обновляющий именованный канал.
372updateNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelFull) '[]
347updateNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelFull) '[]
373updateNamedChannelQ = update_ #channels
348updateNamedChannelQ = update_ #channels
@@ -380,6 +355,7 @@ updateNamedChannelQ = update_ #channels
381 (#namedChannelFullOwner .== param @2 .&& #namedChannelFullId .== param @1)
356 (#namedChannelFullOwner .== param @2 .&& #namedChannelFullId .== param @1)
358+-- |Запрос на каналы пользователя.
383getChannelPostsQ
359getChannelPostsQ
385 -> P.PaginationDirection
361 -> P.PaginationDirection
@@ -398,10 +374,12 @@ getChannelPostsQ lim dir uIds tags = getLastPostsQ
398 Just uIdsQ -> (`in_` uIdsQ)
374 Just uIdsQ -> (`in_` uIdsQ)
399 Nothing -> const $ false
375 Nothing -> const $ false
377+-- |Запрос на все хэштеги.
401getTagsQ :: Query Schema params (RowPG (Only String))
378getTagsQ :: Query Schema params (RowPG (Only String))
402getTagsQ = selectDistinct (unsafeFunction "unnest" #postRowTags `as` #fromOnly) $
379getTagsQ = selectDistinct (unsafeFunction "unnest" #postRowTags `as` #fromOnly) $
403 from (table #posts)
380 from (table #posts)
382+-- |Запорс на создание сообщения.
405createMessageQ :: Manipulation
383createMessageQ :: Manipulation
407 (TuplePG (UserId, Maybe GroupChatId, Maybe UserId, Jsonb (PostElement (MessageCreation))))
385 (TuplePG (UserId, Maybe GroupChatId, Maybe UserId, Jsonb (PostElement (MessageCreation))))
@@ -418,6 +396,7 @@ createMessageQ = insertRow #messages
418 OnConflictDoRaise
396 OnConflictDoRaise
419 (Returning $ #messageStorageId `as` #fromOnly)
397 (Returning $ #messageStorageId `as` #fromOnly)
399+-- |Запрос на создание фантомного сообщения.
421createPhantomMessageQ :: Manipulation Schema (TuplePG (Only GroupChatId)) '[]
400createPhantomMessageQ :: Manipulation Schema (TuplePG (Only GroupChatId)) '[]
422createPhantomMessageQ = insertRow_ #messages
401createPhantomMessageQ = insertRow_ #messages
@@ -429,6 +408,7 @@ createPhantomMessageQ = insertRow_ #messages
429 Set currentTimestamp `as` #messageStorageTime
408 Set currentTimestamp `as` #messageStorageTime
411+-- |Запрос на создание групповой беседы.
432createGroupChatQ :: Manipulation Schema (TuplePG GroupChatCreation) (RowPG (Only GroupChatId))
412createGroupChatQ :: Manipulation Schema (TuplePG GroupChatCreation) (RowPG (Only GroupChatId))
433createGroupChatQ = insertRow #groupChats
413createGroupChatQ = insertRow #groupChats
@@ -439,6 +419,7 @@ createGroupChatQ = insertRow #groupChats
439 OnConflictDoRaise
419 OnConflictDoRaise
440 (Returning $ #groupChatId `as` #fromOnly)
420 (Returning $ #groupChatId `as` #fromOnly)
422+-- |Запрос на обновление групповой беседы.
442updateGroupChatQ :: Manipulation Schema (TuplePG GroupChat) '[]
423updateGroupChatQ :: Manipulation Schema (TuplePG GroupChat) '[]
443updateGroupChatQ = update_ #groupChats
424updateGroupChatQ = update_ #groupChats
@@ -448,23 +429,27 @@ updateGroupChatQ = update_ #groupChats
449 (#groupChatId .== param @1)
430 (#groupChatId .== param @1)
432+-- |Тип строки, воозвращаемой в промежуточном запросе на все диалоги.
451type ChatsQueryResponse = '[
433type ChatsQueryResponse = '[
452 "messageId" ::: 'NotNull (PG UserId),
434 "messageId" ::: 'NotNull (PG UserId),
453 "messageGroupId" ::: 'Null (PG UserId),
435 "messageGroupId" ::: 'Null (PG UserId),
454 "messageUserId" ::: 'Null (PG UserId)
436 "messageUserId" ::: 'Null (PG UserId)
439+-- |Тип оператора сравнения.
457type ConditionOp schema from grouping params nullity0 nullity1 (ty :: PGType)
440type ConditionOp schema from grouping params nullity0 nullity1 (ty :: PGType)
458 = Expression schema from grouping params (nullity0 ty)
441 = Expression schema from grouping params (nullity0 ty)
459 -> Expression schema from grouping params (nullity1 ty)
442 -> Expression schema from grouping params (nullity1 ty)
460 -> Condition schema from grouping params
443 -> Condition schema from grouping params
445+-- |Тип параметров на запрос диалогов.
462type ChatQueryParams = TuplePG
446type ChatQueryParams = TuplePG
464 , Maybe String -- Just UserId as String
448 , Maybe String -- Just UserId as String
465 , Maybe MessageId
449 , Maybe MessageId
452+-- |Запрос на все диалоги.
470 -> P.PaginationDirection
455 -> P.PaginationDirection
@@ -525,6 +510,7 @@ getChatsQ lim dir = select (
525 where_ (isNotNull #messageStorageDestinationGroupId) &
510 where_ (isNotNull #messageStorageDestinationGroupId) &
526 groupBy #messageStorageDestinationGroupId
511 groupBy #messageStorageDestinationGroupId
513+-- |Запрос на сообщения.
528getMessagesQ
514getMessagesQ
530 -> P.PaginationDirection
516 -> P.PaginationDirection
@@ -544,6 +530,7 @@ getMessagesQ lim dir = selectStar (from (table #messages) &
545 ((.^), order) = directionToOperator dir
531 ((.^), order) = directionToOperator dir
533+-- |Запрос на сообщения в групповой беседе.
547getGroupMessagesQ
534getGroupMessagesQ
549 -> P.PaginationDirection
536 -> P.PaginationDirection
@@ -562,12 +549,14 @@ getGroupMessagesQ lim dir = selectStar (from (table #messages) &
562 ((.^), order) = directionToOperator dir
549 ((.^), order) = directionToOperator dir
564-- String -- user id as String
551-- String -- user id as String
552+-- |Запрос на групповую беседу для данного пользователя.
565getGroupChatForUserQ :: Query Schema (TuplePG (String, GroupChatId)) (RowPG GroupChat)
553getGroupChatForUserQ :: Query Schema (TuplePG (String, GroupChatId)) (RowPG GroupChat)
566getGroupChatForUserQ = selectStar $
554getGroupChatForUserQ = selectStar $
567 (from (table #groupChats)) &
555 (from (table #groupChats)) &
568 where_ (#groupChatId .== param @2) &
556 where_ (#groupChatId .== param @2) &
569 where_ (#groupChatUsers .? param @1)
557 where_ (#groupChatUsers .? param @1)
559+-- |Запрос на поиск факультета.
571getFacultySearchResultQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
560getFacultySearchResultQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
572getFacultySearchResultQ = selectStar (from (table #faculties) &
561getFacultySearchResultQ = selectStar (from (table #faculties) &
573 where_ (vector @@ query) &
562 where_ (vector @@ query) &
@@ -588,6 +577,7 @@ getFacultySearchResultQ = selectStar (from (table #faculties) &
588 #facultyPath])
577 #facultyPath])
589 query = tsQuery "russian" (param @1)
578 query = tsQuery "russian" (param @1)
580+-- |Запрос на поиск пользователя.
591searchUsersQ :: Query Schema (TuplePG (Only Text)) (RowPG UserRow)
581searchUsersQ :: Query Schema (TuplePG (Only Text)) (RowPG UserRow)
592searchUsersQ = select (
582searchUsersQ = select (
593 #users ! #userRowId :*
583 #users ! #userRowId :*
@@ -619,19 +609,21 @@ searchUsersQ = select (
620 query = tsQuery' (param @1)
610 query = tsQuery' (param @1)
612+-- |Запрос на теги по популярности.
622tagsByFrquencyQ :: Query Schema params '["tag" ::: 'NotNull (PG Text), "count" ::: 'NotNull 'PGint8]
613tagsByFrquencyQ :: Query Schema params '["tag" ::: 'NotNull (PG Text), "count" ::: 'NotNull 'PGint8]
623tagsByFrquencyQ = select
614tagsByFrquencyQ = select
624 (#fromOnly `as` #tag :* count #fromOnly `as` #count)
615 (#fromOnly `as` #tag :* count #fromOnly `as` #count)
625 (from (subquery $ getTagsQ `As` #tt) &
616 (from (subquery $ getTagsQ `As` #tt) &
626 groupBy #fromOnly)
617 groupBy #fromOnly)
619+-- |Запрос на данной количество самых популярных тегов.
628getNpopularTagsQ :: Limit -> Query Schema param (RowPG (Only Text))
620getNpopularTagsQ :: Limit -> Query Schema param (RowPG (Only Text))
629getNpopularTagsQ lim = select (#tag `as` #fromOnly)
621getNpopularTagsQ lim = select (#tag `as` #fromOnly)
630 (from (subquery $ tagsByFrquencyQ `As` #tt) &
622 (from (subquery $ tagsByFrquencyQ `As` #tt) &
631 orderBy [#count & Desc] &
623 orderBy [#count & Desc] &
632 limit lim)
624 limit lim)
634−
626+-- |Запрос на поиск по тегам.
635searchTagsQ :: Query Schema (TuplePG (Only Text)) (RowPG (Only Text))
627searchTagsQ :: Query Schema (TuplePG (Only Text)) (RowPG (Only Text))
636searchTagsQ = select (#tag `as` #fromOnly) $
628searchTagsQ = select (#tag `as` #fromOnly) $
637 from (subquery (tagsByFrquencyQ `As` #tt)) &
629 from (subquery (tagsByFrquencyQ `As` #tt)) &
@@ -642,6 +634,7 @@ searchTagsQ = select (#tag `as` #fromOnly) $
642 query = tsQuery' (param @1)
634 query = tsQuery' (param @1)
643 vector = tsVector' #tag
635 vector = tsVector' #tag
637+-- |PostgreSQL функция ts_rank_cd
646 :: Expression schema from grouping params ('NotNull 'PGtext)
639 :: Expression schema from grouping params ('NotNull 'PGtext)
647 -> Expression schema from grouping params ('NotNull 'PGtext)
640 -> Expression schema from grouping params ('NotNull 'PGtext)
@@ -649,6 +642,7 @@ tsRankCd
649tsRankCd vector query = UnsafeExpression $
642tsRankCd vector query = UnsafeExpression $
650 "ts_rank_cd" <> parenthesized (commaSeparated ["ARRAY[1,1,1,1]", renderExpression vector, renderExpression query, "2|4|8|16|32"])
643 "ts_rank_cd" <> parenthesized (commaSeparated ["ARRAY[1,1,1,1]", renderExpression vector, renderExpression query, "2|4|8|16|32"])
645+-- |PostgreSQL функция ts_vector
653 :: ByteString -- ^ Language
647 :: ByteString -- ^ Language
654 -> Expression schema from grouping params ('NotNull 'PGtext)
648 -> Expression schema from grouping params ('NotNull 'PGtext)
@@ -656,12 +650,14 @@ tsVector
656tsVector lang x = UnsafeExpression $
650tsVector lang x = UnsafeExpression $
657 "to_tsvector" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
651 "to_tsvector" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
653+-- |PostgreSQL функция ts_vector без языка.
660 :: Expression schema from grouping params ('NotNull 'PGtext)
655 :: Expression schema from grouping params ('NotNull 'PGtext)
661 -> Expression schema from grouping params ('NotNull 'PGtext)
656 -> Expression schema from grouping params ('NotNull 'PGtext)
662tsVector' x = UnsafeExpression $
657tsVector' x = UnsafeExpression $
663 "to_tsvector" <> parenthesized (renderExpression x)
658 "to_tsvector" <> parenthesized (renderExpression x)
660+-- |PostgreSQL функция ts_query.
666 :: ByteString -- ^ Language
662 :: ByteString -- ^ Language
667 -> Expression schema from grouping params ('NotNull 'PGtext)
663 -> Expression schema from grouping params ('NotNull 'PGtext)
@@ -669,32 +665,38 @@ tsQuery
669tsQuery lang x = UnsafeExpression $
665tsQuery lang x = UnsafeExpression $
670 "to_tsquery" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
666 "to_tsquery" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
668+-- |PostgreSQL функция ts_query без языка.
673 :: Expression schema from grouping params ('NotNull 'PGtext)
670 :: Expression schema from grouping params ('NotNull 'PGtext)
674 -> Expression schema from grouping params ('NotNull 'PGtext)
671 -> Expression schema from grouping params ('NotNull 'PGtext)
675tsQuery' x = UnsafeExpression $
672tsQuery' x = UnsafeExpression $
676 "to_tsquery" <> parenthesized (renderExpression x)
673 "to_tsquery" <> parenthesized (renderExpression x)
675+-- |PostgreSQL функция array_to_string
678arrayToText
676arrayToText
679 :: Expression schema from grouping params ('NotNull ('PGvararray ('NotNull 'PGtext)))
677 :: Expression schema from grouping params ('NotNull ('PGvararray ('NotNull 'PGtext)))
680 -> Expression schema from grouping params ('NotNull 'PGtext)
678 -> Expression schema from grouping params ('NotNull 'PGtext)
681arrayToText x = UnsafeExpression $
679arrayToText x = UnsafeExpression $
682 "array_to_string" <> parenthesized (commaSeparated [renderExpression x, "' '"])
680 "array_to_string" <> parenthesized (commaSeparated [renderExpression x, "' '"])
682+-- |PostgreSQL оператор @@
685 :: Expression schema from grouping params (nullity0 'PGtext)
684 :: Expression schema from grouping params (nullity0 'PGtext)
686 -> Expression schema from grouping params (nullity1 'PGtext)
685 -> Expression schema from grouping params (nullity1 'PGtext)
687 -> Expression schema from grouping params (nullity2 'PGbool)
686 -> Expression schema from grouping params (nullity2 'PGbool)
688(@@) = unsafeBinaryOp "@@"
687(@@) = unsafeBinaryOp "@@"
690space :: Expression schema from grouping params ('NotNull 'PGtext)
690space :: Expression schema from grouping params ('NotNull 'PGtext)
691space = UnsafeExpression "' '"
691space = UnsafeExpression "' '"
693+-- |Функция, переводящая список варажений текста в одно выражение текста через пробел.
693textArrayToText
694textArrayToText
694 :: [Expression schema from grouping params ('NotNull 'PGtext)]
695 :: [Expression schema from grouping params ('NotNull 'PGtext)]
695 -> Expression schema from grouping params ('NotNull 'PGtext)
696 -> Expression schema from grouping params ('NotNull 'PGtext)
696textArrayToText = fold . L.intersperse space
697textArrayToText = fold . L.intersperse space
699+-- |Запрос, создающий пользователя.
698createUserQ :: Manipulation Schema (TuplePG UserCreation) (RowPG (Only UserId))
700createUserQ :: Manipulation Schema (TuplePG UserCreation) (RowPG (Only UserId))
699createUserQ = insertRow #users (
701createUserQ = insertRow #users (
700 Default `as` #userRowId :*
702 Default `as` #userRowId :*
@@ -707,12 +709,13 @@ createUserQ = insertRow #users (
707 OnConflictDoRaise
709 OnConflictDoRaise
708 (Returning (#userRowId `as` #fromOnly))
710 (Returning (#userRowId `as` #fromOnly))
712+-- |Запрос, удалющий пользователей, которые не подтвердили свой профиль.
710removeUnverifiedUserQ :: Manipulation Schema (TuplePG (Only UserEmail)) '[]
713removeUnverifiedUserQ :: Manipulation Schema (TuplePG (Only UserEmail)) '[]
711removeUnverifiedUserQ = deleteFrom_ #users
714removeUnverifiedUserQ = deleteFrom_ #users
712 (#userRowEmail .== param @1 .&&
715 (#userRowEmail .== param @1 .&&
713 (not_ . notNull $ #userRowIsValidated))
716 (not_ . notNull $ #userRowIsValidated))
715−
718+-- |Запрос, создающий токен.
716createTokenQ :: Manipulation Schema (TuplePG Token) '[]
719createTokenQ :: Manipulation Schema (TuplePG Token) '[]
717createTokenQ = insertRow_ #tokens (
720createTokenQ = insertRow_ #tokens (
718 Set (param @1) `as` #tokenUserId :*
721 Set (param @1) `as` #tokenUserId :*
@@ -725,6 +728,7 @@ createTokenQ = insertRow_ #tokens (
725 Set (param @8) `as` #tokenDeactivationCode
728 Set (param @8) `as` #tokenDeactivationCode
731+-- |Запрос, обновляющий токен.
728updateTokenQ :: Manipulation Schema (TuplePG Token) '[]
732updateTokenQ :: Manipulation Schema (TuplePG Token) '[]
729updateTokenQ = update_ #tokens (
733updateTokenQ = update_ #tokens (
730 Same `as` #tokenUserId :*
734 Same `as` #tokenUserId :*
@@ -737,10 +741,12 @@ updateTokenQ = update_ #tokens (
737 Set (param @8) `as` #tokenDeactivationCode)
741 Set (param @8) `as` #tokenDeactivationCode)
738 (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
742 (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
744+-- |Запрос, удалющий токен.
740deleteTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) '[]
745deleteTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) '[]
741deleteTokenQ = deleteFrom_ #tokens
746deleteTokenQ = deleteFrom_ #tokens
742 (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
747 (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
749+-- |Запрос, подтверждающий профиль пользователя.
744validateUserQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
750validateUserQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
745validateUserQ = update_ #users (
751validateUserQ = update_ #users (
746 Same `as` #userRowId :*
752 Same `as` #userRowId :*
@@ -752,22 +758,26 @@ validateUserQ = update_ #users (
752 Set true `as` #userRowIsValidated)
758 Set true `as` #userRowIsValidated)
753 (#userRowId .== param @1)
759 (#userRowId .== param @1)
761+-- |Запрос, возвращающий токен.
755getTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
762getTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
756getTokenQ = selectStar (from (table #tokens) &
763getTokenQ = selectStar (from (table #tokens) &
757 where_ (#tokenUserId .== param @1 .&&
764 where_ (#tokenUserId .== param @1 .&&
758 #tokenValue .== param @2))
765 #tokenValue .== param @2))
767+-- |Запрос, возвращающий токен по хэшу кода активации.
760getTokenActivationQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
768getTokenActivationQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
761getTokenActivationQ = selectStar (from (table #tokens) &
769getTokenActivationQ = selectStar (from (table #tokens) &
762 where_ (#tokenUserId .== param @1 .&&
770 where_ (#tokenUserId .== param @1 .&&
763 #tokenActivationCode .== param @2))
771 #tokenActivationCode .== param @2))
773+-- |Запрос, даективирующий токен.
765deactivateTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) (RowPG (Only Text))
774deactivateTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) (RowPG (Only Text))
766deactivateTokenQ = deleteFrom #tokens
775deactivateTokenQ = deleteFrom #tokens
767 (#tokenUserId .== param @1 .&&
776 (#tokenUserId .== param @1 .&&
768 #tokenDeactivationCode .== param @2)
777 #tokenDeactivationCode .== param @2)
769 (Returning (#tokenUserAgent `as` #fromOnly))
778 (Returning (#tokenUserAgent `as` #fromOnly))
780+-- |Запрос, возвращающий подтвержденный токен.
771getVerifiedTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
781getVerifiedTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
772getVerifiedTokenQ = selectStar (from (table #tokens) &
782getVerifiedTokenQ = selectStar (from (table #tokens) &
773 where_ (#tokenUserId .== param @1 .&&
783 where_ (#tokenUserId .== param @1 .&&
@@ -775,14 +785,17 @@ getVerifiedTokenQ = selectStar (from (table #tokens) &
775 isNull #tokenVerificationCode .&&
785 isNull #tokenVerificationCode .&&
776 currentTimestamp .< #tokenExpiryDate))
786 currentTimestamp .< #tokenExpiryDate))
788+-- |Запрос, даективирующий все токены для данного пользователя.
778killAllTokensQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
789killAllTokensQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
779killAllTokensQ = deleteFrom_ #tokens
790killAllTokensQ = deleteFrom_ #tokens
780 (#tokenUserId .== param @1)
791 (#tokenUserId .== param @1)
793+-- |Запрос, удаляющий недействительные токены.
782pruneDeadTokensQ :: Manipulation Schema '[] '[]
794pruneDeadTokensQ :: Manipulation Schema '[] '[]
783pruneDeadTokensQ = deleteFrom_ #tokens
795pruneDeadTokensQ = deleteFrom_ #tokens
784 (#tokenExpiryDate .< currentTimestamp)
796 (#tokenExpiryDate .< currentTimestamp)
798+-- |Запрос, удаляющий неактивированных пользователей.
786pruneGhostUsersQ :: Manipulation Schema '[] '[]
799pruneGhostUsersQ :: Manipulation Schema '[] '[]
787pruneGhostUsersQ = deleteFrom_ #users
800pruneGhostUsersQ = deleteFrom_ #users
788 ((not_ . in_ #userRowId $ select (#tokens ! #tokenUserId `as` #id) (from $ table #tokens)) .&&
801 ((not_ . in_ #userRowId $ select (#tokens ! #tokenUserId `as` #id) (from $ table #tokens)) .&&
@@ -798,11 +811,17 @@ instance HasValidatableText UserCreation where
798 userCreationUserFaculty,
811 userCreationUserFaculty,
799 userCreationUserEmail]
812 userCreationUserEmail]
814+-- |Объект для создания пользователя.
801data UserCreation = UserCreation {
815data UserCreation = UserCreation {
802 userCreationFirstName :: Text,
817 userCreationFirstName :: Text,
803 userCreationMiddleName :: Text,
819 userCreationMiddleName :: Text,
804 userCreationLastName :: Text,
821 userCreationLastName :: Text,
805 userCreationUserFaculty :: FacultyUrl,
823 userCreationUserFaculty :: FacultyUrl,
806 userCreationUserEmail :: Text
825 userCreationUserEmail :: Text
807} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
826} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
@@ -819,42 +838,62 @@ instance FromJSON UserCreation where
819 parseJSON = withObject "user creation" $ \e ->
838 parseJSON = withObject "user creation" $ \e ->
820 UserCreation <$> e .: "firstName" <*> e .: "middleName" <*> e .: "lastName" <*> e .: "faculty" <*> e .: "email"
839 UserCreation <$> e .: "firstName" <*> e .: "middleName" <*> e .: "lastName" <*> e .: "faculty" <*> e .: "email"
841+-- |Объект для обновления пользователя.
822data UserUpdateRow = UserUpdateRow {
842data UserUpdateRow = UserUpdateRow {
843+ -- |Идентификатор пользователя.
823 userUpdateRowId :: UserId,
844 userUpdateRowId :: UserId,
824 userUpdateRowFirstName :: Text,
846 userUpdateRowFirstName :: Text,
825 userUpdateRowMiddleName :: Text,
848 userUpdateRowMiddleName :: Text,
826 userUpdateRowLastName :: Text,
850 userUpdateRowLastName :: Text,
827 userUpdateRowUserFaculty :: FacultyUrl
852 userUpdateRowUserFaculty :: FacultyUrl
828} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
853} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
830−
855+-- |Объект для создания канала.
831data NamedChannelCreation = NamedChannelCreation {
856data NamedChannelCreation = NamedChannelCreation {
857+ -- |Владелец канала.
832 namedChannelCreationOwner :: UserId,
858 namedChannelCreationOwner :: UserId,
859+ -- |Название канала.
833 namedChannelCreationName :: Text,
860 namedChannelCreationName :: Text,
834 namedChannelCreationTags :: Vector Text,
862 namedChannelCreationTags :: Vector Text,
835 namedChannelCreationPeopleIds :: Vector UserId
864 namedChannelCreationPeopleIds :: Vector UserId
836} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
865} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
867+-- |Функция, добавлющая в структуру пользователя.
838addUserToChannelCreate :: UserId -> NamedChannelCreationRequest -> NamedChannelCreation
868addUserToChannelCreate :: UserId -> NamedChannelCreationRequest -> NamedChannelCreation
839addUserToChannelCreate uId (NamedChannelCreationRequest cName cTags cPeople) = NamedChannelCreation uId cName cTags cPeople
869addUserToChannelCreate uId (NamedChannelCreationRequest cName cTags cPeople) = NamedChannelCreation uId cName cTags cPeople
871+-- |Полный объект канала.
841data NamedChannelFull = NamedChannelFull {
872data NamedChannelFull = NamedChannelFull {
842 namedChannelFullId :: NamedChannelId,
874 namedChannelFullId :: NamedChannelId,
843 namedChannelFullOwner :: UserId,
876 namedChannelFullOwner :: UserId,
844 namedChannelFullName :: Text,
878 namedChannelFullName :: Text,
845 namedChannelFullTags :: Vector Text,
880 namedChannelFullTags :: Vector Text,
846 namedChannelFullPeopleIds :: Vector UserId
882 namedChannelFullPeopleIds :: Vector UserId
847} deriving GHC.Generic
883} deriving GHC.Generic
849instance SOP.Generic NamedChannelFull
885instance SOP.Generic NamedChannelFull
850instance SOP.HasDatatypeInfo NamedChannelFull
886instance SOP.HasDatatypeInfo NamedChannelFull
888+-- |Добавляет в структуру пользователя.
852addUserToChannelUpdate :: UserId -> NamedChannel UserId -> NamedChannelFull
889addUserToChannelUpdate :: UserId -> NamedChannel UserId -> NamedChannelFull
853addUserToChannelUpdate uId (NamedChannel cId cName cTags cPeople) = NamedChannelFull cId uId cName cTags cPeople
890addUserToChannelUpdate uId (NamedChannel cId cName cTags cPeople) = NamedChannelFull cId uId cName cTags cPeople
892+-- |Убирает пользователя из структуры.
855removeUserFromChannel :: NamedChannelFull -> NamedChannel UserId
893removeUserFromChannel :: NamedChannelFull -> NamedChannel UserId
856removeUserFromChannel (NamedChannelFull cId _ cName cTags cPeople) = NamedChannel cId cName cTags cPeople
894removeUserFromChannel (NamedChannelFull cId _ cName cTags cPeople) = NamedChannel cId cName cTags cPeople
896+-- |Возвращаает канал для данного человека.
858getChannelForUser :: UserId -> NamedChannelId -> StaticPQ NamedChannelFull
897getChannelForUser :: UserId -> NamedChannelId -> StaticPQ NamedChannelFull
859getChannelForUser uId cId = do
898getChannelForUser uId cId = do
860 channel <- runQueryParams getChannelForUserQ (uId, cId) >>= firstRow
899 channel <- runQueryParams getChannelForUserQ (uId, cId) >>= firstRow
@@ -862,7 +901,7 @@ getChannelForUser uId cId = do
862 (Just c) -> return c
901 (Just c) -> return c
863 Nothing -> lift $ S.throwError S.err404
902 Nothing -> lift $ S.throwError S.err404
865−-- TODO: Reject bad requests. Should be binary.
904+-- |Проверяет, существует ли пользователь.
866verifyUsers :: [UserId] -> StaticPQ ()
905verifyUsers :: [UserId] -> StaticPQ ()
867verifyUsers uIds =
906verifyUsers uIds =
868 case verifiedUserIdsQ uIds of
907 case verifiedUserIdsQ uIds of
@@ -871,6 +910,7 @@ verifyUsers uIds =
871 when (length us /= length uIds) $ lift $ S.throwError impossibleContent
910 when (length us /= length uIds) $ lift $ S.throwError impossibleContent
872 Nothing -> return ()
911 Nothing -> return ()
913+-- |Удаляет групповую беседу.
874deleteGroupChat :: GroupChatId -> StaticPQ ()
914deleteGroupChat :: GroupChatId -> StaticPQ ()
875deleteGroupChat gId = do
915deleteGroupChat gId = do
876 _ <- manipulateParams deleteGroupChatQ (Only gId)
916 _ <- manipulateParams deleteGroupChatQ (Only gId)
@@ -885,6 +925,7 @@ deleteGroupChat gId = do
885 (#messageStorageDestinationGroupId .== param @1)
925 (#messageStorageDestinationGroupId .== param @1)
887-- NOTE: Not transactional
927-- NOTE: Not transactional
928+-- |Создает пользователя.
888createUser :: UserCreation -> StaticPQ UserId
929createUser :: UserCreation -> StaticPQ UserId
889createUser creation = do
930createUser creation = do
890 _ <- manipulateParams removeUnverifiedUserQ (Only $ userCreationUserEmail creation)
931 _ <- manipulateParams removeUnverifiedUserQ (Only $ userCreationUserEmail creation)
@@ -894,6 +935,7 @@ createUser creation = do
894-- MARK: FrontEnd functions
935-- MARK: FrontEnd functions
896-- Nothing <=> no user
937-- Nothing <=> no user
938+-- |Возвращаает посты от данного пользователя.
897getPostsForUser
939getPostsForUser
898 :: Maybe PostId
940 :: Maybe PostId
@@ -904,6 +946,7 @@ getPostsForUser pId lim dir uId = do
904 postRows <- runQueryParams (getLastNPostsForUserQ lim dir) (pId, uId) >>= getRows
946 postRows <- runQueryParams (getLastNPostsForUserQ lim dir) (pId, uId) >>= getRows
905 wrapIntoResponse (fromMaybe [] . rowsToPosts $ postRows)
947 wrapIntoResponse (fromMaybe [] . rowsToPosts $ postRows)
949+-- |Возвращаает посты по идентификатором.
907getPosts :: [PostId] -> StaticPQ (Maybe (ResponseWithUsers [Post]))
950getPosts :: [PostId] -> StaticPQ (Maybe (ResponseWithUsers [Post]))
908getPosts pId =
951getPosts pId =
909 case getPostsByIdQ pId of
952 case getPostsByIdQ pId of
@@ -912,6 +955,7 @@ getPosts pId =
912 rowsToPosts postRows `liftMaybe` wrapIntoResponse
955 rowsToPosts postRows `liftMaybe` wrapIntoResponse
913 Nothing -> return Nothing
956 Nothing -> return Nothing
958+-- |Возвращает последние посты.
915getLastPosts
959getLastPosts
916 :: Maybe PostId
960 :: Maybe PostId
@@ -921,15 +965,19 @@ getLastPosts pId lim dir = do
921 postRows <- runQueryParams (getLastPostsQ id lim dir) (Only pId) >>= getRows
965 postRows <- runQueryParams (getLastPostsQ id lim dir) (Only pId) >>= getRows
922 rowsToPosts postRows `liftMaybe` wrapIntoResponse
966 rowsToPosts postRows `liftMaybe` wrapIntoResponse
968+-- |Возвращает пользователя по адресу почты.
924getUserWithEmail :: UserEmail -> StaticPQ (Maybe (User FacultyUrl))
969getUserWithEmail :: UserEmail -> StaticPQ (Maybe (User FacultyUrl))
925getUserWithEmail email = runQueryParams getUserWithEmailQ (Only email) >>= firstRow
970getUserWithEmail email = runQueryParams getUserWithEmailQ (Only email) >>= firstRow
972+-- |возвращает пользователей по идентификаторам.
927getUsers :: [UserId] -> StaticPQ (Maybe [User Faculty])
973getUsers :: [UserId] -> StaticPQ (Maybe [User Faculty])
928getUsers ids = getUsersQ ids `liftMaybe` (fmap (Just . map rowToUser) . (runQuery >=> getRows))
974getUsers ids = getUsersQ ids `liftMaybe` (fmap (Just . map rowToUser) . (runQuery >=> getRows))
976+-- |Возвращает всех пользователей.
930getAllUsers :: StaticPQ [User Faculty]
977getAllUsers :: StaticPQ [User Faculty]
931getAllUsers = fmap rowToUser <$> (runQuery getAllUsersQ >>= getRows)
978getAllUsers = fmap rowToUser <$> (runQuery getAllUsersQ >>= getRows)
933publishPost :: UserId -> PostCreation -> StaticPQ PostId
981publishPost :: UserId -> PostCreation -> StaticPQ PostId
934publishPost uId pc = commitedTransactionallyUpdate $ do
982publishPost uId pc = commitedTransactionallyUpdate $ do
935 pId' <- manipulateParams createPostRowQ (uId, postCreationTags pc) >>= firstRow
983 pId' <- manipulateParams createPostRowQ (uId, postCreationTags pc) >>= firstRow
@@ -939,6 +987,7 @@ publishPost uId pc = commitedTransactionallyUpdate $ do
939 return pId
987 return pId
940 _ -> lift $ S.throwError S.err404
988 _ -> lift $ S.throwError S.err404
942createNewChannel :: UserId -> NamedChannelCreationRequest -> StaticPQ (Maybe NamedChannelId)
991createNewChannel :: UserId -> NamedChannelCreationRequest -> StaticPQ (Maybe NamedChannelId)
943createNewChannel uId req = commitedTransactionallyUpdate $ do
992createNewChannel uId req = commitedTransactionallyUpdate $ do
944 let uIds = toList $ namedChannelCreationRequestPeopleIds req
993 let uIds = toList $ namedChannelCreationRequestPeopleIds req
@@ -946,9 +995,11 @@ createNewChannel uId req = commitedTransactionallyUpdate $ do
946 cId <- manipulateParams createNamedChannelQ (addUserToChannelCreate uId (req {namedChannelCreationRequestPeopleIds = fromList uIds})) >>= firstRow
995 cId <- manipulateParams createNamedChannelQ (addUserToChannelCreate uId (req {namedChannelCreationRequestPeopleIds = fromList uIds})) >>= firstRow
947 return $ fmap fromOnly cId
996 return $ fmap fromOnly cId
998+-- |Возвращает канал для данного пользователя.
949channelCountForUser :: UserId -> StaticPQ Int64
999channelCountForUser :: UserId -> StaticPQ Int64
950channelCountForUser uId = (fromMaybe 0 . fmap fromOnly) <$> (runQueryParams countChannelsQ (Only uId) >>= firstRow)
1000channelCountForUser uId = (fromMaybe 0 . fmap fromOnly) <$> (runQueryParams countChannelsQ (Only uId) >>= firstRow)
1002+-- |Обновляет канал.
952updateChannel :: UserId -> NamedChannel UserId -> StaticPQ ()
1003updateChannel :: UserId -> NamedChannel UserId -> StaticPQ ()
953updateChannel uId req = do
1004updateChannel uId req = do
954 let uIds = namedChannelPeopleIds req
1005 let uIds = namedChannelPeopleIds req
@@ -957,17 +1008,21 @@ updateChannel uId req = do
957 _ <- commitedTransactionallyUpdate $ manipulateParams updateNamedChannelQ $ addUserToChannelUpdate uId (req {namedChannelPeopleIds = uIds})
1008 _ <- commitedTransactionallyUpdate $ manipulateParams updateNamedChannelQ $ addUserToChannelUpdate uId (req {namedChannelPeopleIds = uIds})
958 return ()
1009 return ()
1011+-- |Возвращает факультет.
960getFaculty :: Text -> StaticPQ Faculty
1012getFaculty :: Text -> StaticPQ Faculty
961getFaculty t = runQueryParams getFacultyQ (Only t) >>= firstRow >>= fromMaybe404
1013getFaculty t = runQueryParams getFacultyQ (Only t) >>= firstRow >>= fromMaybe404
1015+-- |Проверяет, является ли данный факультет валидным.
963isValidFaculty :: FacultyUrl -> StaticPQ Bool
1016isValidFaculty :: FacultyUrl -> StaticPQ Bool
964isValidFaculty url = do
1017isValidFaculty url = do
965 (faculty :: Maybe Faculty) <- runQueryParams getFacultyQ (Only url) >>= firstRow
1018 (faculty :: Maybe Faculty) <- runQueryParams getFacultyQ (Only url) >>= firstRow
966 return $ isJust faculty
1019 return $ isJust faculty
1021+-- |Обновляет факультет.
968updateFaculty :: Faculty -> StaticPQ ()
1022updateFaculty :: Faculty -> StaticPQ ()
969updateFaculty fac = void $ manipulateParams updateFacultyQ fac
1023updateFaculty fac = void $ manipulateParams updateFacultyQ fac
1025+-- |Возвращает посты в канале.
971getChannelPosts
1026getChannelPosts
972 :: UserId
1027 :: UserId
973 -> Maybe PostId
1028 -> Maybe PostId
@@ -986,6 +1041,7 @@ getChannelPosts uId pId lim dir cId = do
986 >>= getRows
1041 >>= getRows
987 fmap (fromMaybe $ ResponseWithUsers mempty mempty) $ rowsToPosts postRows `liftMaybe` wrapIntoResponse
1042 fmap (fromMaybe $ ResponseWithUsers mempty mempty) $ rowsToPosts postRows `liftMaybe` wrapIntoResponse
1044+-- |Возвращает почты в анонимном кнаале.
989getAnonymousChannelPosts
1045getAnonymousChannelPosts
990 :: Maybe PostId
1046 :: Maybe PostId
991 -> Limit
1047 -> Limit
@@ -996,19 +1052,23 @@ getAnonymousChannelPosts pId lim dir (AnonymousChannel tags people) = do
996 postRows <- runQueryParams (getChannelPostsQ lim dir people tags) (Only pId) >>= getRows
1052 postRows <- runQueryParams (getChannelPostsQ lim dir people tags) (Only pId) >>= getRows
997 fmap (fromMaybe $ ResponseWithUsers mempty mempty) $ rowsToPosts postRows `liftMaybe` wrapIntoResponse
1053 fmap (fromMaybe $ ResponseWithUsers mempty mempty) $ rowsToPosts postRows `liftMaybe` wrapIntoResponse
1055+-- |Возвращает все каналы.
999getAllChannels :: UserId -> StaticPQ [NamedChannel UserId]
1056getAllChannels :: UserId -> StaticPQ [NamedChannel UserId]
1000getAllChannels uId = fmap (map removeUserFromChannel) $
1057getAllChannels uId = fmap (map removeUserFromChannel) $
1001 runQueryParams getAllChannelsForUserQ (Only uId) >>= getRows
1058 runQueryParams getAllChannelsForUserQ (Only uId) >>= getRows
1060+-- |Удаляет именованный канал.
1003deleteNamedChannel :: UserId -> NamedChannelId -> StaticPQ ()
1061deleteNamedChannel :: UserId -> NamedChannelId -> StaticPQ ()
1004deleteNamedChannel uId cId = do
1062deleteNamedChannel uId cId = do
1005 _ <- getChannelForUser uId cId
1063 _ <- getChannelForUser uId cId
1006 _ <- commitedTransactionallyUpdate $ manipulateParams deleteNamedChannelQ (Only cId)
1064 _ <- commitedTransactionallyUpdate $ manipulateParams deleteNamedChannelQ (Only cId)
1007 return ()
1065 return ()
1067+-- |Возвращает теги.
1009getTags :: Limit -> StaticPQ [String]
1068getTags :: Limit -> StaticPQ [String]
1010getTags lim = map fromOnly <$> (runQuery (getNpopularTagsQ lim) >>= getRows)
1069getTags lim = map fromOnly <$> (runQuery (getNpopularTagsQ lim) >>= getRows)
1071+-- |Возвращает диалоги.
1012getDialogs
1072getDialogs
1013 :: UserId
1073 :: UserId
1014 -> Maybe MessageId
1074 -> Maybe MessageId
@@ -1019,6 +1079,7 @@ getDialogs uId mId lim dir = do
1019 resp <- runQueryParams (getChatsQ lim dir) (uId, Just $ show uId, mId) >>= getRows
1079 resp <- runQueryParams (getChatsQ lim dir) (uId, Just $ show uId, mId) >>= getRows
1020 (>>= fromMaybe500) $ (responseToDialogs uId resp `liftMaybe` wrapIntoResponse)
1080 (>>= fromMaybe500) $ (responseToDialogs uId resp `liftMaybe` wrapIntoResponse)
1082+-- |Возвращает сообщения в диалоге.
1022getMessagesInUserChat
1083getMessagesInUserChat
1023 :: UserId
1084 :: UserId
1024 -> UserId
1085 -> UserId
@@ -1030,6 +1091,7 @@ getMessagesInUserChat selfId uId mId lim dir = do
1030 resp <- runQueryParams (getMessagesQ lim dir) (selfId, uId, mId) >>= getRows
1091 resp <- runQueryParams (getMessagesQ lim dir) (selfId, uId, mId) >>= getRows
1031 fromMaybe500 . sequence . map restoreMessage $ resp
1092 fromMaybe500 . sequence . map restoreMessage $ resp
1094+-- |Возвращает сообщения в групповой беседе.
1033getMessagesInGroupChat
1095getMessagesInGroupChat
1034 :: UserId
1096 :: UserId
1035 -> GroupChatId
1097 -> GroupChatId
@@ -1042,6 +1104,7 @@ getMessagesInGroupChat selfId gId mId lim dir = do
1042 resp <- runQueryParams (getGroupMessagesQ lim dir) (gId, mId) >>= getRows
1104 resp <- runQueryParams (getGroupMessagesQ lim dir) (gId, mId) >>= getRows
1043 return . catMaybes . map restoreMessage $ resp
1105 return . catMaybes . map restoreMessage $ resp
1107+-- |Отправляет сообщение.
1045sendMessage :: UserId -> MessageCreation -> StaticPQ MessageId
1108sendMessage :: UserId -> MessageCreation -> StaticPQ MessageId
1046sendMessage selfId (MessageCreation (Just gId) uId@Nothing body) = do
1109sendMessage selfId (MessageCreation (Just gId) uId@Nothing body) = do
1047 _ <- getGroupChatForUser selfId gId
1110 _ <- getGroupChatForUser selfId gId
@@ -1055,6 +1118,7 @@ sendMessage selfId (MessageCreation gId@Nothing (Just uId) body) = do
1055 return mId
1118 return mId
1056sendMessage _ _ = lift $ S.throwError S.err400
1119sendMessage _ _ = lift $ S.throwError S.err400
1121+-- |Создает групповую беседу.
1058createGroupChat :: UserId -> GroupChatCreation -> StaticPQ GroupChatId
1122createGroupChat :: UserId -> GroupChatCreation -> StaticPQ GroupChatId
1059createGroupChat uId (GroupChatCreation (Jsonb chatUsers) name) = do
1123createGroupChat uId (GroupChatCreation (Jsonb chatUsers) name) = do
1060 verifyUsers . M.keys $ chatUsers
1124 verifyUsers . M.keys $ chatUsers
@@ -1065,6 +1129,7 @@ createGroupChat uId (GroupChatCreation (Jsonb chatUsers) name) = do
1065 _ <- manipulateParams createPhantomMessageQ (Only chatId)
1129 _ <- manipulateParams createPhantomMessageQ (Only chatId)
1066 return chatId
1130 return chatId
1132+-- |Обновляет групповую беседу.
1068updateGroupChat :: UserId -> GroupChat -> StaticPQ ()
1133updateGroupChat :: UserId -> GroupChat -> StaticPQ ()
1069updateGroupChat uId (GroupChat gId (Jsonb perms) name) = do
1134updateGroupChat uId (GroupChat gId (Jsonb perms) name) = do
1070 verifyUsers . M.keys $ perms
1135 verifyUsers . M.keys $ perms
@@ -1075,6 +1140,7 @@ updateGroupChat uId (GroupChat gId (Jsonb perms) name) = do
1075 let newPerms = M.insert uId userPerm perms
1140 let newPerms = M.insert uId userPerm perms
1076 void $ manipulateParams updateGroupChatQ (GroupChat gId (Jsonb newPerms) name)
1141 void $ manipulateParams updateGroupChatQ (GroupChat gId (Jsonb newPerms) name)
1143+-- |Удаляет пользователя из беседы.
1078leaveGroupChat :: UserId -> GroupChatId -> StaticPQ ()
1144leaveGroupChat :: UserId -> GroupChatId -> StaticPQ ()
1079leaveGroupChat uId gId = commitedTransactionallyUpdate $ do
1145leaveGroupChat uId gId = commitedTransactionallyUpdate $ do
1080 gChat@(GroupChat _ (Jsonb perms) _) <- getGroupChatForUser uId gId
1146 gChat@(GroupChat _ (Jsonb perms) _) <- getGroupChatForUser uId gId
@@ -1083,6 +1149,7 @@ leaveGroupChat uId gId = commitedTransactionallyUpdate $ do
1083 then deleteGroupChat gId
1149 then deleteGroupChat gId
1084 else void $ manipulateParams updateGroupChatQ gChat{groupChatUsers = Jsonb newPerms}
1150 else void $ manipulateParams updateGroupChatQ gChat{groupChatUsers = Jsonb newPerms}
1152+-- |Возвращает беседу для пользователя.
1086getGroupChatForUser :: UserId -> GroupChatId -> StaticPQ GroupChat
1153getGroupChatForUser :: UserId -> GroupChatId -> StaticPQ GroupChat
1087getGroupChatForUser uId gId = do
1154getGroupChatForUser uId gId = do
1088 chat <- runQueryParams getGroupChatForUserQ (show uId, gId) >>= firstRow
1155 chat <- runQueryParams getGroupChatForUserQ (show uId, gId) >>= firstRow
@@ -1090,15 +1157,18 @@ getGroupChatForUser uId gId = do
1090 (Just c) -> return c
1157 (Just c) -> return c
1091 Nothing -> lift $ S.throwError S.err404
1158 Nothing -> lift $ S.throwError S.err404
1160+-- |Проверяет, является ли данная беседа валидной для данного пользователя.
1093groupChatIsValidForUser :: UserId -> GroupChatId -> StaticPQ Bool
1161groupChatIsValidForUser :: UserId -> GroupChatId -> StaticPQ Bool
1094groupChatIsValidForUser uId gId = do
1162groupChatIsValidForUser uId gId = do
1095 (chat :: Maybe GroupChat) <- runQueryParams getGroupChatForUserQ (show uId, gId) >>= firstRow
1163 (chat :: Maybe GroupChat) <- runQueryParams getGroupChatForUserQ (show uId, gId) >>= firstRow
1096 return $ isJust chat
1164 return $ isJust chat
1166+-- |Возвращает каналы по поисковой строке.
1098getFacultyFromQuery :: T.Text -> StaticPQ [Faculty]
1167getFacultyFromQuery :: T.Text -> StaticPQ [Faculty]
1099getFacultyFromQuery query =
1168getFacultyFromQuery query =
1100 runQueryParams getFacultySearchResultQ (Only . queryFromTextAbbr $ query) >>= getRows
1169 runQueryParams getFacultySearchResultQ (Only . queryFromTextAbbr $ query) >>= getRows
1171+-- |Ищет пользователей по строке.
1102searchUsers :: T.Text -> StaticPQ [User Faculty]
1172searchUsers :: T.Text -> StaticPQ [User Faculty]
1103searchUsers query = do
1173searchUsers query = do
1104 unless (validateText query) $ lift $ throwError lengthExceeded
1174 unless (validateText query) $ lift $ throwError lengthExceeded
@@ -1106,37 +1176,45 @@ searchUsers query = do
1106 then return []
1176 then return []
1107 else map rowToUser <$> (runQueryParams searchUsersQ (Only . queryFromText $ query) >>= getRows)
1177 else map rowToUser <$> (runQueryParams searchUsersQ (Only . queryFromText $ query) >>= getRows)
1179+-- |Ищет теги по запосу.
1109searchTags :: T.Text -> StaticPQ [Text]
1180searchTags :: T.Text -> StaticPQ [Text]
1110searchTags "" = return []
1181searchTags "" = return []
1111searchTags query = map fromOnly <$>
1182searchTags query = map fromOnly <$>
1112 (runQueryParams searchTagsQ
1183 (runQueryParams searchTagsQ
1113 (Only . (<> ":*") . T.strip $ query) >>= getRows)
1184 (Only . (<> ":*") . T.strip $ query) >>= getRows)
1115createToken :: Token -> StaticPQ ()
1187createToken :: Token -> StaticPQ ()
1116createToken token = void $ manipulateParams createTokenQ token
1188createToken token = void $ manipulateParams createTokenQ token
1190+-- |Деактивирует все токены для пользователя.
1118killAllTokens :: UserId -> StaticPQ ()
1191killAllTokens :: UserId -> StaticPQ ()
1119killAllTokens = void . manipulateParams killAllTokensQ . Only
1192killAllTokens = void . manipulateParams killAllTokensQ . Only
1194+-- |Удаляет устаревшую информацию про авторизацию.
1121pruneAuth :: StaticPQ ()
1195pruneAuth :: StaticPQ ()
1122pruneAuth = do
1196pruneAuth = do
1123 _ <- commitedTransactionallyUpdate . manipulate $ pruneDeadTokensQ
1197 _ <- commitedTransactionallyUpdate . manipulate $ pruneDeadTokensQ
1124 _ <- commitedTransactionallyUpdate . manipulate $ pruneGhostUsersQ
1198 _ <- commitedTransactionallyUpdate . manipulate $ pruneGhostUsersQ
1125 return ()
1199 return ()
1201+-- |Осуществляет поиск по каналам.
1127searchChannels :: UserId -> Text -> StaticPQ [NamedChannel UserId]
1202searchChannels :: UserId -> Text -> StaticPQ [NamedChannel UserId]
1128searchChannels uId query = fmap (map removeUserFromChannel) $
1203searchChannels uId query = fmap (map removeUserFromChannel) $
1129 runQueryParams searchChannelsForUserQ (uId, queryFromText query) >>= getRows
1204 runQueryParams searchChannelsForUserQ (uId, queryFromText query) >>= getRows
1131-- NOTE: Not transactional
1206-- NOTE: Not transactional
1207+-- |Проверяет, является ли токен валидным.
1132validateToken :: Token -> StaticPQ ()
1208validateToken :: Token -> StaticPQ ()
1133validateToken token = do
1209validateToken token = do
1134 void $ manipulateParams updateTokenQ token{tokenVerificationCode = Nothing, tokenActivationCode = Nothing}
1210 void $ manipulateParams updateTokenQ token{tokenVerificationCode = Nothing, tokenActivationCode = Nothing}
1135 void $ manipulateParams validateUserQ $ Only $ tokenUserId token
1211 void $ manipulateParams validateUserQ $ Only $ tokenUserId token
1213+-- |Даективирует токен.
1137invalidateToken :: UserId -> ByteString -> StaticPQ ()
1214invalidateToken :: UserId -> ByteString -> StaticPQ ()
1138invalidateToken uId bs = void . manipulateParams deleteTokenQ $ (uId, bs)
1215invalidateToken uId bs = void . manipulateParams deleteTokenQ $ (uId, bs)
1217+-- |Пытается активировать токен с помощью кода.
1140tryVerifyToken :: UserId -> ByteString -> Int -> StaticPQ (Maybe Token)
1218tryVerifyToken :: UserId -> ByteString -> Int -> StaticPQ (Maybe Token)
1141tryVerifyToken uId tokenData code = commitedTransactionallyUpdate $ do
1219tryVerifyToken uId tokenData code = commitedTransactionallyUpdate $ do
1142 token' <- runQueryParams getTokenQ (uId, hash tokenData) >>= firstRow
1220 token' <- runQueryParams getTokenQ (uId, hash tokenData) >>= firstRow
@@ -1154,6 +1232,7 @@ tryVerifyToken uId tokenData code = commitedTransactionallyUpdate $ do
1154 _ <- manipulateParams updateTokenQ newToken
1232 _ <- manipulateParams updateTokenQ newToken
1155 return Nothing
1233 return Nothing
1235+-- |Пытается активировать с помощью ключа активации.
1157tryActivateToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1236tryActivateToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1158tryActivateToken uId activationData = do
1237tryActivateToken uId activationData = do
1159 let hData = hash activationData
1238 let hData = hash activationData
@@ -1165,17 +1244,21 @@ tryActivateToken uId activationData = do
1165 then commitedTransactionallyUpdate (validateToken token) >> (return $ Just token)
1244 then commitedTransactionallyUpdate (validateToken token) >> (return $ Just token)
1166 else return Nothing
1245 else return Nothing
1247+-- |Деактивирует токен.
1168deactivateToken :: UserId -> ByteString -> StaticPQ (Maybe Text)
1248deactivateToken :: UserId -> ByteString -> StaticPQ (Maybe Text)
1169deactivateToken uId dData = fmap fromOnly <$> (manipulateParams deactivateTokenQ (uId, hash dData) >>= firstRow)
1249deactivateToken uId dData = fmap fromOnly <$> (manipulateParams deactivateTokenQ (uId, hash dData) >>= firstRow)
1251+-- |Возвращает активированный токен.
1171getVerifiedToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1252getVerifiedToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1172getVerifiedToken uId tokenData = runQueryParams getVerifiedTokenQ (uId, hash tokenData) >>= firstRow
1253getVerifiedToken uId tokenData = runQueryParams getVerifiedTokenQ (uId, hash tokenData) >>= firstRow
1255+-- |Обновляет пользователя.
1174updateUser :: (UserUpdateRow) -> StaticPQ (Maybe UserId)
1256updateUser :: (UserUpdateRow) -> StaticPQ (Maybe UserId)
1175updateUser user = fmap fromOnly <$> (manipulateParams updateUserQ (normalizeUser user) >>= firstRow)
1257updateUser user = fmap fromOnly <$> (manipulateParams updateUserQ (normalizeUser user) >>= firstRow)
1177-- MARK: Utils
1259-- MARK: Utils
1261+-- |Нормализует поля пользователя.
1179normalizeUser :: UserUpdateRow -> UserUpdateRow
1262normalizeUser :: UserUpdateRow -> UserUpdateRow
1180normalizeUser UserUpdateRow{..} = UserUpdateRow {
1263normalizeUser UserUpdateRow{..} = UserUpdateRow {
1181 userUpdateRowId = userUpdateRowId,
1264 userUpdateRowId = userUpdateRowId,
@@ -1185,23 +1268,39 @@ normalizeUser UserUpdateRow{..} = UserUpdateRow {
1185 userUpdateRowUserFaculty = T.toLower . T.strip $ userUpdateRowUserFaculty
1268 userUpdateRowUserFaculty = T.toLower . T.strip $ userUpdateRowUserFaculty
1271+-- |Объект пользователя для ответов с базы данных.
1188data UserRow = UserRow {
1272data UserRow = UserRow {
1273+ -- |Идентификатор пользователя.
1189 userRowId :: UserId,
1274 userRowId :: UserId,
1190 userRowFirstName :: Text,
1276 userRowFirstName :: Text,
1191 userRowMiddleName :: Text,
1278 userRowMiddleName :: Text,
1192 userRowLastName :: Text,
1280 userRowLastName :: Text,
1193 userRowFacultyUrl :: FacultyUrl,
1282 userRowFacultyUrl :: FacultyUrl,
1194 userRowEmail :: Text,
1284 userRowEmail :: Text,
1285+ -- |Был ли профиль подтвержден через почту.
1195 userRowIsValidated :: Bool,
1286 userRowIsValidated :: Bool,
1287+ -- |Название факультета.
1196 userRowFacultyName :: T.Text,
1288 userRowFacultyName :: T.Text,
1289+ -- |Адрес сайта факультета.
1197 userRowFacultyURL :: FacultyUrl,
1290 userRowFacultyURL :: FacultyUrl,
1291+ -- |Вспомогательная информация о факультете.
1198 userRowFacultyPath :: T.Text,
1292 userRowFacultyPath :: T.Text,
1199 userRowFacultyCampusName :: T.Text,
1294 userRowFacultyCampusName :: T.Text,
1200 userRowFacultyCampusCode :: T.Text,
1296 userRowFacultyCampusCode :: T.Text,
1297+ -- |Теги департамента.
1201 userRowFacultyTags :: V.Vector T.Text,
1298 userRowFacultyTags :: V.Vector T.Text,
1299+ -- |АДрес департамента.
1202 userRowFacultyAddress :: T.Text
1300 userRowFacultyAddress :: T.Text
1203} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
1301} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
1303+-- |Функция, переводящая ответ с базы данных в пользователя.
1205rowToUser :: UserRow -> User Faculty
1304rowToUser :: UserRow -> User Faculty
1206rowToUser UserRow{..} = User {
1305rowToUser UserRow{..} = User {
1207 userId = userRowId,
1306 userId = userRowId,
@@ -1220,6 +1319,7 @@ rowToUser UserRow{..} = User {
1220 userEmail = userRowEmail
1319 userEmail = userRowEmail
1322+-- |Переводит строку в запрос с учетом аббревиатур.
1223queryFromTextAbbr :: Text -> Text
1323queryFromTextAbbr :: Text -> Text
1224queryFromTextAbbr = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isAlphaNum)
1324queryFromTextAbbr = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isAlphaNum)
@@ -1230,12 +1330,14 @@ queryFromTextAbbr = T.unwords . L.intersperse "&" . map processTerm . filter (no
1230 else mempty
1330 else mempty
1231 ) <> ")"
1331 ) <> ")"
1333+-- |Переводит строку в запорс.
1233queryFromText :: Text -> Text
1334queryFromText :: Text -> Text
1234queryFromText = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isPrint)
1335queryFromText = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isPrint)
1236 processTerm :: Text -> Text
1337 processTerm :: Text -> Text
1237 processTerm t = t <> ":*"
1338 processTerm t = t <> ":*"
1340+-- |Перевод направление в оператор.
1239directionToOperator
1341directionToOperator
1240 :: P.PaginationDirection
1342 :: P.PaginationDirection
1241 -> (ConditionOp schema0 from0 grouping0 params0 nullity0 nullity1 (ty :: PGType),
1343 -> (ConditionOp schema0 from0 grouping0 params0 nullity0 nullity1 (ty :: PGType),
@@ -1248,6 +1350,7 @@ foldMaybe [] = Just []
1248foldMaybe (Nothing : _) = Nothing
1350foldMaybe (Nothing : _) = Nothing
1249foldMaybe (Just x : xs) = (x :) <$> foldMaybe xs
1351foldMaybe (Just x : xs) = (x :) <$> foldMaybe xs
1353+-- |переводит элементы поста с базы данных в объект поста.
1251rowsToPosts :: [PostRowResponse] -> Maybe [Post]
1354rowsToPosts :: [PostRowResponse] -> Maybe [Post]
1252rowsToPosts = foldMaybe . map rowsToPost . L.groupBy ((==) `on` postRowId)
1355rowsToPosts = foldMaybe . map rowsToPost . L.groupBy ((==) `on` postRowId)
@@ -1261,11 +1364,15 @@ idsToColumn :: [Int64] -> Maybe (Query schema params '["id" ::: 'NotNull 'PGint8
1261idsToColumn [] = Nothing
1364idsToColumn [] = Nothing
1262idsToColumn (i:ii) = Just $ values (unsafeIntToExpr i `as` #id) $ map ((`as` #id) . unsafeIntToExpr) ii
1365idsToColumn (i:ii) = Just $ values (unsafeIntToExpr i `as` #id) $ map ((`as` #id) . unsafeIntToExpr) ii
1367+-- |Небезопасное переведение числа в SQL выражение.
1264unsafeIntToExpr :: Int64 -> Expression schema from grouping params ty
1368unsafeIntToExpr :: Int64 -> Expression schema from grouping params ty
1265unsafeIntToExpr = UnsafeExpression . pack . show
1369unsafeIntToExpr = UnsafeExpression . pack . show
1371+-- |Ответ сервера с пользователями.
1267data ResponseWithUsers r = ResponseWithUsers {
1372data ResponseWithUsers r = ResponseWithUsers {
1268 response :: r,
1374 response :: r,
1269 users :: M.Map UserId (User Faculty)
1376 users :: M.Map UserId (User Faculty)
1270} deriving (Generic)
1377} deriving (Generic)
@@ -1296,6 +1403,7 @@ instance (Foldable t, HasUsers r) => HasUsers (t r) where
1296instance HasUsers Post where
1403instance HasUsers Post where
1297 userSet = Set.singleton . postAuthorId
1404 userSet = Set.singleton . postAuthorId
1406+-- |Оборачивает ответ в пользователей.
1299wrapIntoUsers :: r -> Set.Set UserId -> StaticPQ (Maybe (ResponseWithUsers r))
1407wrapIntoUsers :: r -> Set.Set UserId -> StaticPQ (Maybe (ResponseWithUsers r))
1300wrapIntoUsers r us
1408wrapIntoUsers r us
1301 | Set.null us = return . Just $ ResponseWithUsers r M.empty
1409 | Set.null us = return . Just $ ResponseWithUsers r M.empty