@@ -1,16 +1,13 @@
1{-# LANGUAGE
1{-# LANGUAGE
2− DataKinds,
2+ DataKinds ,
3− DeriveGeneric,
3+ DeriveGeneric ,
4 OverloadedLabels,
4 OverloadedLabels,
5− OverloadedStrings,
5+ OverloadedStrings ,
6− TypeApplications,
6+ TypeApplications ,
7 TypeOperators,
7 TypeOperators,
8 PartialTypeSignatures,
8 PartialTypeSignatures,
9 FlexibleInstances,
9 FlexibleInstances,
10− KindSignatures,
10+ KindSignatures #-}
13− ScopedTypeVariables #-}
15{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
12{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
@@ -19,7 +16,7 @@ module Data.Query (
20 createTables,
17 createTables,
22− -- getUser,
19+ getUser,
24 getAllUsers,
21 getAllUsers,
25 getLastPosts,
22 getLastPosts,
@@ -46,28 +43,8 @@ module Data.Query (
46 getGroupChatForUser,
43 getGroupChatForUser,
47 getFaculty,
44 getFaculty,
48 updateFaculty,
45 updateFaculty,
49− getFacultyFromQuery,
46+ getFacultyFromQuery
69− groupChatIsValidForUser
72import Squeal.PostgreSQL
49import Squeal.PostgreSQL
73import Data.User
50import Data.User
@@ -96,7 +73,7 @@ import Data.Text (Text)
96import qualified Data.Text as T
73import qualified Data.Text as T
97import Data.Channel.NamedChannel
74import Data.Channel.NamedChannel
98import Data.Channel.AnonymousChannel
75import Data.Channel.AnonymousChannel
99−import Data.Maybe (fromMaybe, catMaybes, isJust)
76+import Data.Maybe (fromMaybe)
100import Squeal.PostgreSQL.Render
77import Squeal.PostgreSQL.Render
101import Data.GroupChat
78import Data.GroupChat
102import Data.Message
79import Data.Message
@@ -106,10 +83,6 @@ import Data.Faculty
106import Data.ByteString (ByteString)
83import Data.ByteString (ByteString)
107import Data.Foldable (fold)
84import Data.Foldable (fold)
108import Data.Char
85import Data.Char
109−import qualified Data.Vector as V
110−import Server.Auth.Token
112−import Data.Text.Validator
114-- MARK: Documentation
87-- MARK: Documentation
@@ -172,70 +145,26 @@ getPostQ oTe te = select (
172-- let rows = M.fromList $ map (tupleBy $ quoteRowId . head) . groupBy ((==) `on` quoteRowId) . sortBy (compare `on` quoteRowId) $ rows'
145-- let rows = M.fromList $ map (tupleBy $ quoteRowId . head) . groupBy ((==) `on` quoteRowId) . sortBy (compare `on` quoteRowId) $ rows'
173-- return $ M.lookup qId rows >>= rowsToQuote rows
146-- return $ M.lookup qId rows >>= rowsToQuote rows
175−getUserWithEmailQ :: Query Schema (TuplePG (Only UserEmail)) (RowPG (User FacultyUrl))
148+getUserQ :: Query Schema (TuplePG (Only UserId)) (RowPG User)
176−getUserWithEmailQ = select (
177− #userRowId `as` #userId :*
178− #userRowFirstName `as` #firstName :*
179− #userRowMiddleName `as` #middleName :*
180− #userRowLastName `as` #lastName :*
181− #userRowFacultyUrl `as` #userFaculty :*
182− #userRowEmail `as` #userEmail
183− ) (from (table #users) &
149+getUserQ = selectStar $ from (table #users) & where_ (#userId .== param @1)
184− where_ (#userRowEmail .== param @1) &
185− where_ (notNull #userRowIsValidated))
187verifiedUserIdsQ :: [UserId] -> Maybe (Query Schema '[] (RowPG (Only UserId)))
151verifiedUserIdsQ :: [UserId] -> Maybe (Query Schema '[] (RowPG (Only UserId)))
188verifiedUserIdsQ uIds = case idsToColumn uIds of
152verifiedUserIdsQ uIds = case idsToColumn uIds of
189− Just idQ -> Just $ select (#users ! #userRowId `as` #fromOnly) $ from (subquery (idQ `As` #ids) &
153+ Just idQ -> Just $ select (#users ! #userId `as` #fromOnly) $ from (subquery (idQ `As` #ids) &
190 innerJoin (table #users)
154 innerJoin (table #users)
191− (#ids ! #id .== #users ! #userRowId))
155+ (#ids ! #id .== #users ! #userId))
192 Nothing -> Nothing
156 Nothing -> Nothing
194−getUsersQ :: [UserId] -> Maybe (Query Schema '[] (RowPG UserRow))
159+getUsersQ :: [UserId] -> Maybe (Query Schema '[] (RowPG User))
195getUsersQ uIds = case idsToColumn uIds of
160getUsersQ uIds = case idsToColumn uIds of
196− Just idQ -> Just $ select (
197− #users ! #userRowId :*
198− #users ! #userRowFirstName :*
199− #users ! #userRowMiddleName :*
200− #users ! #userRowLastName :*
201− #users ! #userRowFacultyUrl :*
202− #users ! #userRowEmail :*
203− #users ! #userRowIsValidated :*
204− #faculties ! #facultyName `as` #userRowFacultyName :*
205− #faculties ! #facultyUrl `as` #userRowFacultyURL :*
206− #faculties ! #facultyPath `as` #userRowFacultyPath :*
207− #faculties ! #facultyCampusName `as` #userRowFacultyCampusName :*
208− #faculties ! #facultyCampusCode `as` #userRowFacultyCampusCode :*
209− #faculties ! #facultyTags `as` #userRowFacultyTags :*
210− #faculties ! #facultyAddress `as` #userRowFacultyAddress
211− ) (from (subquery (idQ `As` #ids) &
161+ Just idQ -> Just $ selectDotStar #users $ from (subquery (idQ `As` #ids) &
212 innerJoin (table #users)
162 innerJoin (table #users)
213− (#ids ! #id .== #users ! #userRowId) &
163+ (#ids ! #id .== #users ! #userId))
214− innerJoin (table #faculties)
215− (#users ! #userRowFacultyUrl .== #faculties ! #facultyUrl)) &
216− where_ (notNull $ #users ! #userRowIsValidated))
217 Nothing -> Nothing
164 Nothing -> Nothing
219−getAllUsersQ :: Query Schema '[] (RowPG UserRow)
166+getAllUsersQ :: Query Schema '[] (RowPG User)
220−getAllUsersQ = select (
167+getAllUsersQ = selectStar $ from $ table #users
221− #users ! #userRowId :*
222− #users ! #userRowFirstName :*
223− #users ! #userRowMiddleName :*
224− #users ! #userRowLastName :*
225− #users ! #userRowFacultyUrl :*
226− #users ! #userRowEmail :*
227− #users ! #userRowIsValidated :*
228− #faculties ! #facultyName `as` #userRowFacultyName :*
229− #faculties ! #facultyUrl `as` #userRowFacultyURL :*
230− #faculties ! #facultyPath `as` #userRowFacultyPath :*
231− #faculties ! #facultyCampusName `as` #userRowFacultyCampusName :*
232− #faculties ! #facultyCampusCode `as` #userRowFacultyCampusCode :*
233− #faculties ! #facultyTags `as` #userRowFacultyTags :*
234− #faculties ! #facultyAddress `as` #userRowFacultyAddress
235− ) (from ((table #users) &
236− innerJoin (table #faculties)
237− (#users ! #userRowFacultyUrl .== #faculties ! #facultyUrl))&
238− where_ (notNull $ #users ! #userRowIsValidated))
240getPostsByIdQ :: [PostId] -> Maybe (Query Schema '[] (RowPG PostRowResponse))
169getPostsByIdQ :: [PostId] -> Maybe (Query Schema '[] (RowPG PostRowResponse))
241getPostsByIdQ pIds = case idsToColumn pIds of
170getPostsByIdQ pIds = case idsToColumn pIds of
@@ -297,57 +226,28 @@ getChannelForUserQ = selectStar $
297 from (table #channels) &
226 from (table #channels) &
298 where_ (#namedChannelFullOwner .== param @1 .&& #namedChannelFullId .== param @2)
227 where_ (#namedChannelFullOwner .== param @1 .&& #namedChannelFullId .== param @2)
300−updateUserQ :: Manipulation Schema (TuplePG (UserUpdateRow)) (RowPG (Only UserId))
301−updateUserQ = update #users (
302− Same `as` #userRowId :*
303− Set (param @2) `as` #userRowFirstName :*
304− Set (param @3) `as` #userRowMiddleName :*
305− Set (param @4) `as` #userRowLastName :*
306− Set (param @5) `as` #userRowFacultyUrl :*
307− Same `as` #userRowEmail :*
308− Same `as` #userRowIsValidated)
309− (#userRowId .== param @1)
310− (Returning $ #userRowId `as` #fromOnly)
312getAllChannelsForUserQ :: Query Schema (TuplePG (Only UserId)) (RowPG NamedChannelFull)
229getAllChannelsForUserQ :: Query Schema (TuplePG (Only UserId)) (RowPG NamedChannelFull)
313getAllChannelsForUserQ = selectStar $
230getAllChannelsForUserQ = selectStar $
314 from (table #channels) &
231 from (table #channels) &
315 where_ (#namedChannelFullOwner .== param @1) &
232 where_ (#namedChannelFullOwner .== param @1) &
316 orderBy [#namedChannelFullId & Desc]
233 orderBy [#namedChannelFullId & Desc]
318−searchChannelsForUserQ :: Query Schema (TuplePG (UserId, Text)) (RowPG NamedChannelFull)
319−searchChannelsForUserQ = selectStar $
320− from (table #channels) &
321− where_ (#namedChannelFullOwner .== param @1) &
323− tsRankCd vector1 query & Desc,
324− tsRankCd vector query & Desc
327− vector = tsVector' (textArrayToText [
328− #namedChannelFullName,
329− unsafeFunction "unnest" #namedChannelFullTags
331− vector1 = tsVector' #namedChannelFullName
332− query = tsQuery' (param @2)
334updateFacultyQ :: Manipulation Schema (TuplePG Faculty) '[]
235updateFacultyQ :: Manipulation Schema (TuplePG Faculty) '[]
335updateFacultyQ = insertRow #faculties
236updateFacultyQ = insertRow #faculties
337 Set (param @1) `as` #facultyName :*
238 Set (param @1) `as` #facultyName :*
338− Set (param @2) `as` #facultyUrl :*
239+ Set (param @2) `as` #facultyURL :*
339 Set (param @3) `as` #facultyPath :*
240 Set (param @3) `as` #facultyPath :*
340 Set (param @4) `as` #facultyCampusName :*
241 Set (param @4) `as` #facultyCampusName :*
341 Set (param @5) `as` #facultyCampusCode :*
242 Set (param @5) `as` #facultyCampusCode :*
342− Set (param @6) `as` #facultyTags :*
243+ Set (param @6) `as` #facultyTags
343− Set (param @7) `as` #facultyAddress
345 (OnConflictDoNothing)
245 (OnConflictDoNothing)
346 (Returning Nil)
246 (Returning Nil)
348getFacultyQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
248getFacultyQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
349getFacultyQ = selectStar (from (table #faculties) &
249getFacultyQ = selectStar (from (table #faculties) &
350− where_ (#facultyUrl .== param @1))
250+ where_ (#facultyURL .== param @1))
352createNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelCreation) (RowPG (Only NamedChannelId))
252createNamedChannelQ :: Manipulation Schema (TuplePG NamedChannelCreation) (RowPG (Only NamedChannelId))
353createNamedChannelQ = insertRow #channels
253createNamedChannelQ = insertRow #channels
@@ -361,11 +261,6 @@ createNamedChannelQ = insertRow #channels
361 OnConflictDoRaise
261 OnConflictDoRaise
362 (Returning $ #namedChannelFullId `as` #fromOnly)
262 (Returning $ #namedChannelFullId `as` #fromOnly)
364−countChannelsQ :: Query Schema (TuplePG (Only UserId)) (RowPG (Only Int64))
365−countChannelsQ = select (countStar `as` #fromOnly) (from (table #channels) &
366− where_ (#namedChannelFullOwner .== param @1) &
367− groupBy #namedChannelFullOwner)
369deleteNamedChannelQ :: Manipulation Schema (TuplePG (Only NamedChannelId)) '[]
264deleteNamedChannelQ :: Manipulation Schema (TuplePG (Only NamedChannelId)) '[]
370deleteNamedChannelQ = deleteFrom_ #channels (#namedChannelFullId .== param @1)
265deleteNamedChannelQ = deleteFrom_ #channels (#namedChannelFullId .== param @1)
@@ -398,7 +293,7 @@ getChannelPostsQ lim dir uIds tags = getLastPostsQ
398 Just uIdsQ -> (`in_` uIdsQ)
293 Just uIdsQ -> (`in_` uIdsQ)
399 Nothing -> const $ false
294 Nothing -> const $ false
401−getTagsQ :: Query Schema params (RowPG (Only String))
296+getTagsQ :: Query Schema '[] (RowPG (Only String))
402getTagsQ = selectDistinct (unsafeFunction "unnest" #postRowTags `as` #fromOnly) $
297getTagsQ = selectDistinct (unsafeFunction "unnest" #postRowTags `as` #fromOnly) $
403 from (table #posts)
298 from (table #posts)
@@ -409,26 +304,15 @@ createMessageQ :: Manipulation
409createMessageQ = insertRow #messages
304createMessageQ = insertRow #messages
411 Default `as` #messageStorageId :*
306 Default `as` #messageStorageId :*
412− Set (notNull $ param @1) `as` #messageStorageAuthorId :*
307+ Set (param @1) `as` #messageStorageAuthorId :*
413 Set (param @2) `as` #messageStorageDestinationGroupId :*
308 Set (param @2) `as` #messageStorageDestinationGroupId :*
414 Set (param @3) `as` #messageStorageDestinationUserId :*
309 Set (param @3) `as` #messageStorageDestinationUserId :*
415− Set (notNull $ param @4) `as` #messageStorageBody :*
310+ Set (param @4) `as` #messageStorageBody :*
416 Set currentTimestamp `as` #messageStorageTime
311 Set currentTimestamp `as` #messageStorageTime
418 OnConflictDoRaise
313 OnConflictDoRaise
419 (Returning $ #messageStorageId `as` #fromOnly)
314 (Returning $ #messageStorageId `as` #fromOnly)
421−createPhantomMessageQ :: Manipulation Schema (TuplePG (Only GroupChatId)) '[]
422−createPhantomMessageQ = insertRow_ #messages
424− Default `as` #messageStorageId :*
425− Set null_ `as` #messageStorageAuthorId :*
426− Set (notNull $ param @1) `as` #messageStorageDestinationGroupId :*
427− Set null_ `as` #messageStorageDestinationUserId :*
428− Set null_ `as` #messageStorageBody :*
429− Set currentTimestamp `as` #messageStorageTime
432createGroupChatQ :: Manipulation Schema (TuplePG GroupChatCreation) (RowPG (Only GroupChatId))
316createGroupChatQ :: Manipulation Schema (TuplePG GroupChatCreation) (RowPG (Only GroupChatId))
433createGroupChatQ = insertRow #groupChats
317createGroupChatQ = insertRow #groupChats
@@ -504,7 +388,7 @@ getChatsQ lim dir = select (
504 (ifThenElse
388 (ifThenElse
505 (#messageStorageAuthorId .== param @1)
389 (#messageStorageAuthorId .== param @1)
506 #messageStorageDestinationUserId
390 #messageStorageDestinationUserId
507− #messageStorageAuthorId) `as` #messageUserId) $
391+ (notNull #messageStorageAuthorId)) `as` #messageUserId) $
508 from (table #messages) &
392 from (table #messages) &
509 where_ (isNotNull #messageStorageDestinationUserId .&&
393 where_ (isNotNull #messageStorageDestinationUserId .&&
510 (#messageStorageAuthorId .== param @1 .||
394 (#messageStorageAuthorId .== param @1 .||
@@ -571,83 +455,21 @@ getGroupChatForUserQ = selectStar $
571getFacultySearchResultQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
455getFacultySearchResultQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
572getFacultySearchResultQ = selectStar (from (table #faculties) &
456getFacultySearchResultQ = selectStar (from (table #faculties) &
573 where_ (vector @@ query) &
457 where_ (vector @@ query) &
575− tsRankCd vector1 query & Desc,
576− tsRankCd vector2 query & Desc,
577− tsRankCd vector query & Desc
458+ orderBy [tsRankCd vector query & Desc])
580 vector = tsVector "russian" (textArrayToText [
460 vector = tsVector "russian" (textArrayToText [
581 #facultyName,
461 #facultyName,
582 #facultyPath,
462 #facultyPath,
583 #facultyCampusName,
463 #facultyCampusName,
584 (arrayToText #facultyTags)])
464 (arrayToText #facultyTags)])
585− vector1 = tsVector "russian" #facultyName
586− vector2 = tsVector "russian" (textArrayToText [
589− query = tsQuery "russian" (param @1)
465+ query = tsQuery (param @1)
591−searchUsersQ :: Query Schema (TuplePG (Only Text)) (RowPG UserRow)
592−searchUsersQ = select (
593− #users ! #userRowId :*
594− #users ! #userRowFirstName :*
595− #users ! #userRowMiddleName :*
596− #users ! #userRowLastName :*
597− #users ! #userRowFacultyUrl :*
598− #users ! #userRowEmail :*
599− #users ! #userRowIsValidated :*
600− #faculties ! #facultyName `as` #userRowFacultyName :*
601− #faculties ! #facultyUrl `as` #userRowFacultyURL :*
602− #faculties ! #facultyPath `as` #userRowFacultyPath :*
603− #faculties ! #facultyCampusName `as` #userRowFacultyCampusName :*
604− #faculties ! #facultyCampusCode `as` #userRowFacultyCampusCode :*
605− #faculties ! #facultyTags `as` #userRowFacultyTags :*
606− #faculties ! #facultyAddress `as` #userRowFacultyAddress
607− ) (from ((table #users) &
608− innerJoin (table #faculties)
609− (#users ! #userRowFacultyUrl .== #faculties ! #facultyUrl)) &
610− where_ (notNull $ #users ! #userRowIsValidated) &
611− where_ (vector @@ query) &
612− orderBy [tsRankCd vector query & Desc] &
615− vector = tsVector' (textArrayToText [
616− #users ! #userRowFirstName,
617− #users ! #userRowMiddleName,
618− #users ! #userRowLastName
620− query = tsQuery' (param @1)
622−tagsByFrquencyQ :: Query Schema params '["tag" ::: 'NotNull (PG Text), "count" ::: 'NotNull 'PGint8]
623−tagsByFrquencyQ = select
624− (#fromOnly `as` #tag :* count #fromOnly `as` #count)
625− (from (subquery $ getTagsQ `As` #tt) &
628−getNpopularTagsQ :: Limit -> Query Schema param (RowPG (Only Text))
629−getNpopularTagsQ lim = select (#tag `as` #fromOnly)
630− (from (subquery $ tagsByFrquencyQ `As` #tt) &
631− orderBy [#count & Desc] &
635−searchTagsQ :: Query Schema (TuplePG (Only Text)) (RowPG (Only Text))
636−searchTagsQ = select (#tag `as` #fromOnly) $
637− from (subquery (tagsByFrquencyQ `As` #tt)) &
638− where_ (vector @@ query) &
639− orderBy [#count & Desc] &
642− query = tsQuery' (param @1)
643− vector = tsVector' #tag
646 :: Expression schema from grouping params ('NotNull 'PGtext)
468 :: Expression schema from grouping params ('NotNull 'PGtext)
647 -> Expression schema from grouping params ('NotNull 'PGtext)
469 -> Expression schema from grouping params ('NotNull 'PGtext)
648 -> Expression schema from grouping params ('NotNull 'PGfloat4)
470 -> Expression schema from grouping params ('NotNull 'PGfloat4)
649tsRankCd vector query = UnsafeExpression $
471tsRankCd vector query = UnsafeExpression $
650− "ts_rank_cd" <> parenthesized (commaSeparated ["ARRAY[1,1,1,1]", renderExpression vector, renderExpression query, "2|4|8|16|32"])
472+ "ts_rank_cd" <> parenthesized (commaSeparated . map renderExpression $ [vector, query])
653 :: ByteString -- ^ Language
475 :: ByteString -- ^ Language
@@ -656,24 +478,10 @@ tsVector
656tsVector lang x = UnsafeExpression $
478tsVector lang x = UnsafeExpression $
657 "to_tsvector" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
479 "to_tsvector" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
660− :: Expression schema from grouping params ('NotNull 'PGtext)
661− -> Expression schema from grouping params ('NotNull 'PGtext)
662−tsVector' x = UnsafeExpression $
663− "to_tsvector" <> parenthesized (renderExpression x)
666− :: ByteString -- ^ Language
667− -> Expression schema from grouping params ('NotNull 'PGtext)
668− -> Expression schema from grouping params ('NotNull 'PGtext)
669−tsQuery lang x = UnsafeExpression $
670− "to_tsquery" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
673 :: Expression schema from grouping params ('NotNull 'PGtext)
482 :: Expression schema from grouping params ('NotNull 'PGtext)
674 -> Expression schema from grouping params ('NotNull 'PGtext)
483 -> Expression schema from grouping params ('NotNull 'PGtext)
675−tsQuery' x = UnsafeExpression $
484+tsQuery = unsafeFunction "to_tsquery"
676− "to_tsquery" <> parenthesized (renderExpression x)
678arrayToText
486arrayToText
679 :: Expression schema from grouping params ('NotNull ('PGvararray ('NotNull 'PGtext)))
487 :: Expression schema from grouping params ('NotNull ('PGvararray ('NotNull 'PGtext)))
@@ -695,145 +503,17 @@ textArrayToText
695 -> Expression schema from grouping params ('NotNull 'PGtext)
503 -> Expression schema from grouping params ('NotNull 'PGtext)
696textArrayToText = fold . L.intersperse space
504textArrayToText = fold . L.intersperse space
698−createUserQ :: Manipulation Schema (TuplePG UserCreation) (RowPG (Only UserId))
699−createUserQ = insertRow #users (
700− Default `as` #userRowId :*
701− Set (param @1) `as` #userRowFirstName :*
702− Set (param @2) `as` #userRowMiddleName :*
703− Set (param @3) `as` #userRowLastName :*
704− Set (param @4) `as` #userRowFacultyUrl :*
705− Set (param @5) `as` #userRowEmail :*
706− Set false `as` #userRowIsValidated)
708− (Returning (#userRowId `as` #fromOnly))
710−removeUnverifiedUserQ :: Manipulation Schema (TuplePG (Only UserEmail)) '[]
711−removeUnverifiedUserQ = deleteFrom_ #users
712− (#userRowEmail .== param @1 .&&
713− (not_ . notNull $ #userRowIsValidated))
716−createTokenQ :: Manipulation Schema (TuplePG Token) '[]
717−createTokenQ = insertRow_ #tokens (
718− Set (param @1) `as` #tokenUserId :*
719− Set (param @2) `as` #tokenValue :*
720− Set (param @3) `as` #tokenExpiryDate :*
721− Set (param @4) `as` #tokenVerificationCode :*
722− Set (param @5) `as` #tokenActivationTriesLeft :*
723− Set (param @6) `as` #tokenUserAgent :*
724− Set (param @7) `as` #tokenActivationCode :*
725− Set (param @8) `as` #tokenDeactivationCode
728−updateTokenQ :: Manipulation Schema (TuplePG Token) '[]
729−updateTokenQ = update_ #tokens (
730− Same `as` #tokenUserId :*
731− Same `as` #tokenValue :*
732− Set (param @3) `as` #tokenExpiryDate :*
733− Set (param @4) `as` #tokenVerificationCode :*
734− Set (param @5) `as` #tokenActivationTriesLeft :*
735− Set (param @6) `as` #tokenUserAgent :*
736− Set (param @7) `as` #tokenActivationCode :*
737− Set (param @8) `as` #tokenDeactivationCode)
738− (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
740−deleteTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) '[]
741−deleteTokenQ = deleteFrom_ #tokens
742− (#tokenUserId .== param @1 .&& #tokenValue .== param @2)
744−validateUserQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
745−validateUserQ = update_ #users (
746− Same `as` #userRowId :*
747− Same `as` #userRowFirstName :*
748− Same `as` #userRowMiddleName :*
749− Same `as` #userRowLastName :*
750− Same `as` #userRowFacultyUrl :*
751− Same `as` #userRowEmail :*
752− Set true `as` #userRowIsValidated)
753− (#userRowId .== param @1)
755−getTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
756−getTokenQ = selectStar (from (table #tokens) &
757− where_ (#tokenUserId .== param @1 .&&
758− #tokenValue .== param @2))
760−getTokenActivationQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
761−getTokenActivationQ = selectStar (from (table #tokens) &
762− where_ (#tokenUserId .== param @1 .&&
763− #tokenActivationCode .== param @2))
765−deactivateTokenQ :: Manipulation Schema (TuplePG (UserId, ByteString)) (RowPG (Only Text))
766−deactivateTokenQ = deleteFrom #tokens
767− (#tokenUserId .== param @1 .&&
768− #tokenDeactivationCode .== param @2)
769− (Returning (#tokenUserAgent `as` #fromOnly))
771−getVerifiedTokenQ :: Query Schema (TuplePG (UserId, ByteString)) (RowPG Token)
772−getVerifiedTokenQ = selectStar (from (table #tokens) &
773− where_ (#tokenUserId .== param @1 .&&
774− #tokenValue .== param @2 .&&
775− isNull #tokenVerificationCode .&&
776− currentTimestamp .< #tokenExpiryDate))
778−killAllTokensQ :: Manipulation Schema (TuplePG (Only UserId)) '[]
779−killAllTokensQ = deleteFrom_ #tokens
780− (#tokenUserId .== param @1)
782−pruneDeadTokensQ :: Manipulation Schema '[] '[]
783−pruneDeadTokensQ = deleteFrom_ #tokens
784− (#tokenExpiryDate .< currentTimestamp)
786−pruneGhostUsersQ :: Manipulation Schema '[] '[]
787−pruneGhostUsersQ = deleteFrom_ #users
788− ((not_ . in_ #userRowId $ select (#tokens ! #tokenUserId `as` #id) (from $ table #tokens)) .&&
789− (not_ . notNull $ #userRowIsValidated))
791-- MARK: FrontEnd Data Structures
506-- MARK: FrontEnd Data Structures
793−instance HasValidatableText UserCreation where
794− validateText UserCreation{..} = all validateText [
795− userCreationFirstName,
796− userCreationMiddleName,
797− userCreationLastName,
798− userCreationUserFaculty,
799− userCreationUserEmail]
801−data UserCreation = UserCreation {
802− userCreationFirstName :: Text,
803− userCreationMiddleName :: Text,
804− userCreationLastName :: Text,
805− userCreationUserFaculty :: FacultyUrl,
806− userCreationUserEmail :: Text
807−} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
809−instance ToJSON UserCreation where
810− toJSON (UserCreation fName mName lName faculty email) = object [
811− "firstName" .= fName,
812− "middleName" .= mName,
813− "lastName" .= lName,
814− "faculty" .= faculty,
818−instance FromJSON UserCreation where
819− parseJSON = withObject "user creation" $ \e ->
820− UserCreation <$> e .: "firstName" <*> e .: "middleName" <*> e .: "lastName" <*> e .: "faculty" <*> e .: "email"
822−data UserUpdateRow = UserUpdateRow {
823− userUpdateRowId :: UserId,
824− userUpdateRowFirstName :: Text,
825− userUpdateRowMiddleName :: Text,
826− userUpdateRowLastName :: Text,
827− userUpdateRowUserFaculty :: FacultyUrl
828−} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
831data NamedChannelCreation = NamedChannelCreation {
508data NamedChannelCreation = NamedChannelCreation {
832 namedChannelCreationOwner :: UserId,
509 namedChannelCreationOwner :: UserId,
833 namedChannelCreationName :: Text,
510 namedChannelCreationName :: Text,
834 namedChannelCreationTags :: Vector Text,
511 namedChannelCreationTags :: Vector Text,
835 namedChannelCreationPeopleIds :: Vector UserId
512 namedChannelCreationPeopleIds :: Vector UserId
836−} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
513+} deriving GHC.Generic
515+instance SOP.Generic NamedChannelCreation
516+instance SOP.HasDatatypeInfo NamedChannelCreation
838addUserToChannelCreate :: UserId -> NamedChannelCreationRequest -> NamedChannelCreation
518addUserToChannelCreate :: UserId -> NamedChannelCreationRequest -> NamedChannelCreation
839addUserToChannelCreate uId (NamedChannelCreationRequest cName cTags cPeople) = NamedChannelCreation uId cName cTags cPeople
519addUserToChannelCreate uId (NamedChannelCreationRequest cName cTags cPeople) = NamedChannelCreation uId cName cTags cPeople
@@ -863,13 +543,11 @@ getChannelForUser uId cId = do
863 Nothing -> lift $ S.throwError S.err404
543 Nothing -> lift $ S.throwError S.err404
865-- TODO: Reject bad requests. Should be binary.
545-- TODO: Reject bad requests. Should be binary.
866−verifyUsers :: [UserId] -> StaticPQ ()
546+verifiedUsers :: [UserId] -> StaticPQ [UserId]
867−verifyUsers uIds =
547+verifiedUsers uIds =
868 case verifiedUserIdsQ uIds of
548 case verifiedUserIdsQ uIds of
870− (us :: [UserId]) <- fmap fromOnly <$> (runQuery uIdsQ >>= getRows)
549+ Just uIdsQ -> fmap fromOnly <$> (runQuery uIdsQ >>= getRows)
871− when (length us /= length uIds) $ lift $ S.throwError impossibleContent
872− Nothing -> return ()
550+ Nothing -> return []
874deleteGroupChat :: GroupChatId -> StaticPQ ()
552deleteGroupChat :: GroupChatId -> StaticPQ ()
875deleteGroupChat gId = do
553deleteGroupChat gId = do
@@ -884,12 +562,7 @@ deleteGroupChat gId = do
884 deleteGroupChatMessagesQ = deleteFrom_ #messages
562 deleteGroupChatMessagesQ = deleteFrom_ #messages
885 (#messageStorageDestinationGroupId .== param @1)
563 (#messageStorageDestinationGroupId .== param @1)
887−-- NOTE: Not transactional
565+
888−createUser :: UserCreation -> StaticPQ UserId
889−createUser creation = do
890− _ <- manipulateParams removeUnverifiedUserQ (Only $ userCreationUserEmail creation)
891− rowThing <- manipulateParams createUserQ creation >>= firstRow >>= fromMaybe500
892− return (fromOnly rowThing)
894-- MARK: FrontEnd functions
567-- MARK: FrontEnd functions
@@ -921,50 +594,40 @@ getLastPosts pId lim dir = do
921 postRows <- runQueryParams (getLastPostsQ id lim dir) (Only pId) >>= getRows
594 postRows <- runQueryParams (getLastPostsQ id lim dir) (Only pId) >>= getRows
922 rowsToPosts postRows `liftMaybe` wrapIntoResponse
595 rowsToPosts postRows `liftMaybe` wrapIntoResponse
924−getUserWithEmail :: UserEmail -> StaticPQ (Maybe (User FacultyUrl))
597+getUser :: UserId -> StaticPQ User
925−getUserWithEmail email = runQueryParams getUserWithEmailQ (Only email) >>= firstRow
598+getUser uId = runQueryParams getUserQ (Only uId) >>= getRow 0
927−getUsers :: [UserId] -> StaticPQ (Maybe [User Faculty])
600+getUsers :: [UserId] -> StaticPQ (Maybe [User])
928−getUsers ids = getUsersQ ids `liftMaybe` (fmap (Just . map rowToUser) . (runQuery >=> getRows))
601+getUsers ids = getUsersQ ids `liftMaybe` (fmap Just . (runQuery >=> getRows))
930−getAllUsers :: StaticPQ [User Faculty]
603+getAllUsers :: StaticPQ [User]
931−getAllUsers = fmap rowToUser <$> (runQuery getAllUsersQ >>= getRows)
604+getAllUsers = runQuery getAllUsersQ >>= getRows
933publishPost :: UserId -> PostCreation -> StaticPQ PostId
606publishPost :: UserId -> PostCreation -> StaticPQ PostId
934−publishPost uId pc = commitedTransactionallyUpdate $ do
607+publishPost uId pc = commitedTransactionallyUpdate $ do
935 pId' <- manipulateParams createPostRowQ (uId, postCreationTags pc) >>= firstRow
608 pId' <- manipulateParams createPostRowQ (uId, postCreationTags pc) >>= firstRow
936 case pId' of
609 case pId' of
937 (Just (Only pId)) -> do
610 (Just (Only pId)) -> do
938− traversePrepared_ createPostElementRowsQ $ elementsToRows pId (map stripPostElement $ postCreationBody pc)
611+ traversePrepared_ createPostElementRowsQ $ elementsToRows pId (postCreationBody pc)
939 return pId
612 return pId
940 _ -> lift $ S.throwError S.err404
613 _ -> lift $ S.throwError S.err404
942createNewChannel :: UserId -> NamedChannelCreationRequest -> StaticPQ (Maybe NamedChannelId)
615createNewChannel :: UserId -> NamedChannelCreationRequest -> StaticPQ (Maybe NamedChannelId)
943createNewChannel uId req = commitedTransactionallyUpdate $ do
616createNewChannel uId req = commitedTransactionallyUpdate $ do
944− let uIds = toList $ namedChannelCreationRequestPeopleIds req
617+ uIds <- verifiedUsers . toList $ namedChannelCreationRequestPeopleIds req
946 cId <- manipulateParams createNamedChannelQ (addUserToChannelCreate uId (req {namedChannelCreationRequestPeopleIds = fromList uIds})) >>= firstRow
618 cId <- manipulateParams createNamedChannelQ (addUserToChannelCreate uId (req {namedChannelCreationRequestPeopleIds = fromList uIds})) >>= firstRow
947 return $ fmap fromOnly cId
619 return $ fmap fromOnly cId
949−channelCountForUser :: UserId -> StaticPQ Int64
950−channelCountForUser uId = (fromMaybe 0 . fmap fromOnly) <$> (runQueryParams countChannelsQ (Only uId) >>= firstRow)
952updateChannel :: UserId -> NamedChannel UserId -> StaticPQ ()
621updateChannel :: UserId -> NamedChannel UserId -> StaticPQ ()
953−updateChannel uId req = do
622+updateChannel uId req = commitedTransactionallyUpdate $ do
954− let uIds = namedChannelPeopleIds req
623+ uIds <- fmap fromList . verifiedUsers . toList $ namedChannelPeopleIds req
955− verifyUsers (toList uIds)
956 _ <- getChannelForUser uId $ namedChannelId req
624 _ <- getChannelForUser uId $ namedChannelId req
957− _ <- commitedTransactionallyUpdate $ manipulateParams updateNamedChannelQ $ addUserToChannelUpdate uId (req {namedChannelPeopleIds = uIds})
625+ _ <- manipulateParams updateNamedChannelQ $ addUserToChannelUpdate uId (req {namedChannelPeopleIds = uIds})
958 return ()
626 return ()
960getFaculty :: Text -> StaticPQ Faculty
628getFaculty :: Text -> StaticPQ Faculty
961getFaculty t = runQueryParams getFacultyQ (Only t) >>= firstRow >>= fromMaybe404
629getFaculty t = runQueryParams getFacultyQ (Only t) >>= firstRow >>= fromMaybe404
963−isValidFaculty :: FacultyUrl -> StaticPQ Bool
964−isValidFaculty url = do
965− (faculty :: Maybe Faculty) <- runQueryParams getFacultyQ (Only url) >>= firstRow
966− return $ isJust faculty
968updateFaculty :: Faculty -> StaticPQ ()
631updateFaculty :: Faculty -> StaticPQ ()
969updateFaculty fac = void $ manipulateParams updateFacultyQ fac
632updateFaculty fac = void $ manipulateParams updateFacultyQ fac
@@ -1001,13 +664,13 @@ getAllChannels uId = fmap (map removeUserFromChannel) $
1001 runQueryParams getAllChannelsForUserQ (Only uId) >>= getRows
664 runQueryParams getAllChannelsForUserQ (Only uId) >>= getRows
1003deleteNamedChannel :: UserId -> NamedChannelId -> StaticPQ ()
666deleteNamedChannel :: UserId -> NamedChannelId -> StaticPQ ()
1004−deleteNamedChannel uId cId = do
667+deleteNamedChannel uId cId = commitedTransactionallyUpdate $ do
1005 _ <- getChannelForUser uId cId
668 _ <- getChannelForUser uId cId
1006− _ <- commitedTransactionallyUpdate $ manipulateParams deleteNamedChannelQ (Only cId)
669+ _ <- manipulateParams deleteNamedChannelQ (Only cId)
1007 return ()
670 return ()
1009−getTags :: Limit -> StaticPQ [String]
672+getTags :: StaticPQ [String]
1010−getTags lim = map fromOnly <$> (runQuery (getNpopularTagsQ lim) >>= getRows)
673+getTags = map fromOnly <$> (runQuery getTagsQ >>= getRows)
1012getDialogs
675getDialogs
1013 :: UserId
676 :: UserId
@@ -1040,40 +703,36 @@ getMessagesInGroupChat
1040getMessagesInGroupChat selfId gId mId lim dir = do
703getMessagesInGroupChat selfId gId mId lim dir = do
1041 _ <- getGroupChatForUser selfId gId
704 _ <- getGroupChatForUser selfId gId
1042 resp <- runQueryParams (getGroupMessagesQ lim dir) (gId, mId) >>= getRows
705 resp <- runQueryParams (getGroupMessagesQ lim dir) (gId, mId) >>= getRows
1043− return . catMaybes . map restoreMessage $ resp
706+ (return . sequence . map restoreMessage $ resp) >>= fromMaybe500
1045sendMessage :: UserId -> MessageCreation -> StaticPQ MessageId
708sendMessage :: UserId -> MessageCreation -> StaticPQ MessageId
1046−sendMessage selfId (MessageCreation (Just gId) uId@Nothing (Jsonb body)) = do
709+sendMessage selfId (MessageCreation (Just gId) uId@Nothing body) = do
1047 _ <- getGroupChatForUser selfId gId
710 _ <- getGroupChatForUser selfId gId
1048− (Only mId) <- manipulateParams createMessageQ (selfId, Just gId, uId, Jsonb $ stripPostElement body)
711+ (Only mId) <- manipulateParams createMessageQ (selfId, Just gId, uId, body)
1049 >>= firstRow >>= fromMaybe500
712 >>= firstRow >>= fromMaybe500
1050 return mId
713 return mId
1051−sendMessage selfId (MessageCreation gId@Nothing (Just uId) (Jsonb body)) = do
714+sendMessage selfId (MessageCreation gId@Nothing (Just uId) body) = do
1053− (Only mId) <- manipulateParams createMessageQ (selfId, gId, Just uId, Jsonb $ stripPostElement body)
715+ (Only mId) <- manipulateParams createMessageQ (selfId, gId, Just uId, body)
1054 >>= firstRow >>= fromMaybe500
716 >>= firstRow >>= fromMaybe500
1055 return mId
717 return mId
1056sendMessage _ _ = lift $ S.throwError S.err400
718sendMessage _ _ = lift $ S.throwError S.err400
1058createGroupChat :: UserId -> GroupChatCreation -> StaticPQ GroupChatId
720createGroupChat :: UserId -> GroupChatCreation -> StaticPQ GroupChatId
1059createGroupChat uId (GroupChatCreation (Jsonb chatUsers) name) = do
721createGroupChat uId (GroupChatCreation (Jsonb chatUsers) name) = do
1060− verifyUsers . M.keys $ chatUsers
1061− commitedTransactionallyUpdate $ do
1062− let chatUsers' = M.insert uId maxChatPermissions chatUsers
722+ let chatUsers' = M.insert uId maxChatPermissions chatUsers
1063− (Only chatId) <- manipulateParams createGroupChatQ (GroupChatCreation (Jsonb chatUsers') name)
723+ (Only chatId) <- manipulateParams createGroupChatQ (GroupChatCreation (Jsonb chatUsers') name)
1064− >>= firstRow >>= fromMaybe500
724+ >>= firstRow >>= fromMaybe500
1065− _ <- manipulateParams createPhantomMessageQ (Only chatId)
725+ -- TODO: Do somehting with this
726+ _ <- sendMessage uId $ MessageCreation (Just chatId) Nothing (Jsonb $ Markdown "henlo")
1066− return chatId
727+ return chatId
1068updateGroupChat :: UserId -> GroupChat -> StaticPQ ()
729updateGroupChat :: UserId -> GroupChat -> StaticPQ ()
1069−updateGroupChat uId (GroupChat gId (Jsonb perms) name) = do
730+updateGroupChat uId (GroupChat gId (Jsonb perms) name) = commitedTransactionallyUpdate $ do
1070− verifyUsers . M.keys $ perms
1071− commitedTransactionallyUpdate $ do
1072− (GroupChat _ (Jsonb perms') _) <- getGroupChatForUser uId gId
731+ (GroupChat _ (Jsonb perms') _) <- getGroupChatForUser uId gId
1073− let userPerm = fromMaybe minChatPermissions $ M.lookup uId perms'
732+ let userPerm = fromMaybe minChatPermissions $ M.lookup uId perms'
1074− unless (isAdmin userPerm) $ lift $ S.throwError $ S.err401
733+ unless (isAdmin userPerm) $ lift $ S.throwError $ S.err401
1075− let newPerms = M.insert uId userPerm perms
734+ let newPerms = M.insert uId userPerm perms
1076− void $ manipulateParams updateGroupChatQ (GroupChat gId (Jsonb newPerms) name)
735+ void $ manipulateParams updateGroupChatQ (GroupChat gId (Jsonb newPerms) name)
1078leaveGroupChat :: UserId -> GroupChatId -> StaticPQ ()
737leaveGroupChat :: UserId -> GroupChatId -> StaticPQ ()
1079leaveGroupChat uId gId = commitedTransactionallyUpdate $ do
738leaveGroupChat uId gId = commitedTransactionallyUpdate $ do
@@ -1090,151 +749,14 @@ getGroupChatForUser uId gId = do
1090 (Just c) -> return c
749 (Just c) -> return c
1091 Nothing -> lift $ S.throwError S.err404
750 Nothing -> lift $ S.throwError S.err404
1093−groupChatIsValidForUser :: UserId -> GroupChatId -> StaticPQ Bool
1094−groupChatIsValidForUser uId gId = do
1095− (chat :: Maybe GroupChat) <- runQueryParams getGroupChatForUserQ (show uId, gId) >>= firstRow
1096− return $ isJust chat
1098getFacultyFromQuery :: T.Text -> StaticPQ [Faculty]
752getFacultyFromQuery :: T.Text -> StaticPQ [Faculty]
1099getFacultyFromQuery query =
753getFacultyFromQuery query =
1100− runQueryParams getFacultySearchResultQ (Only . queryFromTextAbbr $ query) >>= getRows
754+ runQueryParams getFacultySearchResultQ (Only . queryFromText $ query) >>= getRows
1102−searchUsers :: T.Text -> StaticPQ [User Faculty]
1103−searchUsers query = do
1104− unless (validateText query) $ lift $ throwError lengthExceeded
1105− if (T.null . T.filter isAlpha $ query)
1107− else map rowToUser <$> (runQueryParams searchUsersQ (Only . queryFromText $ query) >>= getRows)
1109−searchTags :: T.Text -> StaticPQ [Text]
1110−searchTags "" = return []
1111−searchTags query = map fromOnly <$>
1112− (runQueryParams searchTagsQ
1113− (Only . (<> ":*") . T.strip $ query) >>= getRows)
1115−createToken :: Token -> StaticPQ ()
1116−createToken token = void $ manipulateParams createTokenQ token
1118−killAllTokens :: UserId -> StaticPQ ()
1119−killAllTokens = void . manipulateParams killAllTokensQ . Only
1121−pruneAuth :: StaticPQ ()
1123− _ <- commitedTransactionallyUpdate . manipulate $ pruneDeadTokensQ
1124− _ <- commitedTransactionallyUpdate . manipulate $ pruneGhostUsersQ
1127−searchChannels :: UserId -> Text -> StaticPQ [NamedChannel UserId]
1128−searchChannels uId query = fmap (map removeUserFromChannel) $
1129− runQueryParams searchChannelsForUserQ (uId, queryFromText query) >>= getRows
1131−-- NOTE: Not transactional
1132−validateToken :: Token -> StaticPQ ()
1133−validateToken token = do
1134− void $ manipulateParams updateTokenQ token{tokenVerificationCode = Nothing, tokenActivationCode = Nothing}
1135− void $ manipulateParams validateUserQ $ Only $ tokenUserId token
1137−invalidateToken :: UserId -> ByteString -> StaticPQ ()
1138−invalidateToken uId bs = void . manipulateParams deleteTokenQ $ (uId, bs)
1140−tryVerifyToken :: UserId -> ByteString -> Int -> StaticPQ (Maybe Token)
1141−tryVerifyToken uId tokenData code = commitedTransactionallyUpdate $ do
1142− token' <- runQueryParams getTokenQ (uId, hash tokenData) >>= firstRow
1144− Nothing -> return Nothing
1146− if (tokenVerificationCode token == Just (hashVerificationCode code))
1147− then validateToken token >> (return $ Just token)
1149− let triesLeft = tokenActivationTriesLeft token - 1
1151− then invalidateToken (tokenUserId token) (tokenValue token) >> return Nothing
1153− let newToken = token{tokenActivationTriesLeft = triesLeft}
1154− _ <- manipulateParams updateTokenQ newToken
1157−tryActivateToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1158−tryActivateToken uId activationData = do
1159− let hData = hash activationData
1160− token' <- runQueryParams getTokenActivationQ (uId, hData) >>= firstRow
1162− Nothing -> return Nothing
1164− if (tokenActivationCode token == Just hData)
1165− then commitedTransactionallyUpdate (validateToken token) >> (return $ Just token)
1166− else return Nothing
1168−deactivateToken :: UserId -> ByteString -> StaticPQ (Maybe Text)
1169−deactivateToken uId dData = fmap fromOnly <$> (manipulateParams deactivateTokenQ (uId, hash dData) >>= firstRow)
1171−getVerifiedToken :: UserId -> ByteString -> StaticPQ (Maybe Token)
1172−getVerifiedToken uId tokenData = runQueryParams getVerifiedTokenQ (uId, hash tokenData) >>= firstRow
1174−updateUser :: (UserUpdateRow) -> StaticPQ (Maybe UserId)
1175−updateUser user = fmap fromOnly <$> (manipulateParams updateUserQ (normalizeUser user) >>= firstRow)
1177-- MARK: Utils
756-- MARK: Utils
1179−normalizeUser :: UserUpdateRow -> UserUpdateRow
1180−normalizeUser UserUpdateRow{..} = UserUpdateRow {
1181− userUpdateRowId = userUpdateRowId,
1182− userUpdateRowFirstName = T.strip $ userUpdateRowFirstName,
1183− userUpdateRowMiddleName = T.strip $ userUpdateRowMiddleName,
1184− userUpdateRowLastName = T.strip $ userUpdateRowLastName,
1185− userUpdateRowUserFaculty = T.toLower . T.strip $ userUpdateRowUserFaculty
1188−data UserRow = UserRow {
1189− userRowId :: UserId,
1190− userRowFirstName :: Text,
1191− userRowMiddleName :: Text,
1192− userRowLastName :: Text,
1193− userRowFacultyUrl :: FacultyUrl,
1194− userRowEmail :: Text,
1195− userRowIsValidated :: Bool,
1196− userRowFacultyName :: T.Text,
1197− userRowFacultyURL :: FacultyUrl,
1198− userRowFacultyPath :: T.Text,
1199− userRowFacultyCampusName :: T.Text,
1200− userRowFacultyCampusCode :: T.Text,
1201− userRowFacultyTags :: V.Vector T.Text,
1202− userRowFacultyAddress :: T.Text
1203−} deriving (GHC.Generic, SOP.Generic, SOP.HasDatatypeInfo)
1205−rowToUser :: UserRow -> User Faculty
1206−rowToUser UserRow{..} = User {
1207− userId = userRowId,
1208− firstName = userRowFirstName,
1209− middleName = userRowMiddleName,
1210− lastName = userRowLastName,
1211− userFaculty = Faculty {
1212− facultyName = userRowFacultyName,
1213− facultyUrl = userRowFacultyURL,
1214− facultyPath = userRowFacultyPath,
1215− facultyCampusName = userRowFacultyCampusName,
1216− facultyCampusCode = userRowFacultyCampusCode,
1217− facultyTags = userRowFacultyTags,
1218− facultyAddress = userRowFacultyAddress
1220− userEmail = userRowEmail
1223−queryFromTextAbbr :: Text -> Text
1224−queryFromTextAbbr = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isAlphaNum)
1226− processTerm :: Text -> Text
1227− processTerm t = "(" <> t <> ":*" <> (
1229− then (" | (" <>) . (<> ")") . T.unwords . L.intersperse "<->" . map (<> ":*") . map T.singleton . T.unpack $ t
1233queryFromText :: Text -> Text
758queryFromText :: Text -> Text
1234−queryFromText = T.unwords . L.intersperse "&" . map processTerm . filter (not . T.null) . T.split (not . isPrint)
759+queryFromText = T.unwords . L.intersperse "&" . map (`T.append` ":*") . filter (not . T.null) . T.split (not . isAlphaNum)
1236− processTerm :: Text -> Text
1237− processTerm t = t <> ":*"
1239directionToOperator
761directionToOperator
1240 :: P.PaginationDirection
762 :: P.PaginationDirection
@@ -1266,7 +788,7 @@ unsafeIntToExpr = UnsafeExpression . pack . show
1267data ResponseWithUsers r = ResponseWithUsers {
789data ResponseWithUsers r = ResponseWithUsers {
1268 response :: r,
790 response :: r,
1269− users :: M.Map UserId (User Faculty)
791+ users :: M.Map UserId User
1270} deriving (Generic)
792} deriving (Generic)
1272instance (ToJSON r) => ToJSON (ResponseWithUsers r)
794instance (ToJSON r) => ToJSON (ResponseWithUsers r)