on master help sign in
Actually resolved #1.

Resolved #22.

commit2158807c9d16d6bdb0c762412bc05276cde9cdf9 authoriko <ilyakooo0@gmail.com> dateTue 5 Mar 2019, 19:50 (8 years ago) parent2482476
5 files changed+28−53
denis/src/Data/Post.hs+10−13 denis/src/Data/PostElement.hs−14 denis/src/Data/Query.hs+12−10 denis/src/Data/Schema.hs+4−10 denis/src/Server/API.hs+2−6
denis/src/Data/Post.hs+10−13
@@ -10,12 +10,6 @@
1010module Data.Post (
1111 Post(..),
1212 PostElement,
13− -- PostQuote(..),
14− -- PostRow,
15− -- PostQuoteRow,
16− -- ElementRow,
17− postToRows,
18− -- postToElementRows,
1913 rowsToPost,
2014 PostId,
2115 QuoteId,
@@ -31,11 +25,14 @@ import Data.Proxy
3125import Data.PostElement
3226import Data.Text (Text)
3327import Data.Function (on)
28+import Data.Time.Clock
29+import Data.Time.Calendar
3430
3531-- MARK: Documentation
3632
3733instance ToSample Post where
38− toSamples _ = samples $ [Post 8 17] <*> (map snd $ toSamples Proxy)
34+ toSamples _ = samples $ [Post 8 17 time] <*> (map snd $ toSamples Proxy)
35+ where time = UTCTime (ModifiedJulianDay 1000) 8
3936
4037
4138-- MARK: Actual type
@@ -46,13 +43,15 @@ type QuoteId = Int64
4643data Post = Post {
4744 postId :: Int64,
4845 postAuthorId :: Int64,
46+ updated :: UTCTime,
4947 postBody :: [PostElement Post]
5048}
5149
5250instance ToJSON Post where
53− toJSON (Post pId aId pb) = object [
51+ toJSON (Post pId aId tm pb) = object [
5452 "id" .= pId,
5553 "authorId" .= aId,
54+ "updated" .= tm,
5655 "body" .= pb ]
5756
5857
@@ -64,6 +63,7 @@ data PostRowResponse = PostRowResponse {
6463 -- PostRow
6564 postRowId :: Int64,
6665 postRowAuthorId :: Int64,
66+ postRowUpdateTime :: UTCTime,
6767
6868 -- ElementRow
6969 rowElementOrd :: Int64,
@@ -78,13 +78,10 @@ instance SOP.Generic PostRowResponse
7878instance SOP.HasDatatypeInfo PostRowResponse
7979
8080unRow :: MkElementRow x -> PostRowResponse -> x
81−unRow f' (PostRowResponse _ _ _ a b c d e) = f' a b c d e
82−
83−postToRows :: Post -> [PostRowResponse]
84−postToRows (Post pId uId els) = map (\(el, f) -> elemenToRow f el) . zip els . map (PostRowResponse pId uId) $ [0..]
81+unRow f' (PostRowResponse _ _ _ _ a b c d e) = f' a b c d e
8582
8683rowsToPost :: [PostRowResponse] -> Maybe Post
8784rowsToPost [] = Nothing
8885rowsToPost (el:els) = if all (((==) `on` postRowId) el) els
89− then Post (postRowId el) (postRowAuthorId el) <$> traverse (unRow rowsToElement) (el:els)
86+ then Post (postRowId el) (postRowAuthorId el) (postRowUpdateTime el) <$> traverse (unRow rowsToElement) (el:els)
9087 else Nothing
denis/src/Data/PostElement.hs−14
@@ -42,20 +42,6 @@ data PostElement a = Markdown Text
4242 | Quote PostQuote
4343 | Attachment Text
4444
45−
46−-- data ElementRow a = ElementRow {
47−-- rowElementId :: Int64, -- the source id
48−-- rowElementOrd :: Int64,
49−-- rowElementMarkdown :: Maybe Text,
50−-- rowElementLatex :: Maybe Text,
51−-- rowElementImage :: Maybe Text,
52−-- rowElementQuote :: Maybe Int64,
53−-- rowElementAttachment :: Maybe Text
54−-- } deriving (GHC.Generic)
55−
56−-- instance SOP.Generic (ElementRow a)
57−-- instance SOP.HasDatatypeInfo (ElementRow a)
58−
5945instance ToJSON (PostElement t) where
6046 toJSON (Markdown m) = object ["markdown" .= m]
6147 toJSON (Latex l) = object ["latex" .= l]
denis/src/Data/Query.hs+12−10
@@ -51,6 +51,7 @@ getPostQ :: TableEndo Schema params _ 'Ungrouped -> TableEndo Schema params _ 'U
5151getPostQ oTe te = select (
5252 #posts ! #postRowId :*
5353 #posts ! #postRowAuthorId :*
54+ #posts ! #postRowUpdateTime :*
5455 -- #rowElementId :*
5556 #postElements ! #rowElementOrd :*
5657 #postElements ! #rowElementMarkdown :*
@@ -92,29 +93,30 @@ type Limit = Word64
9293
9394getLastNPostsQ :: Limit -> Query Schema params (RowPG PostRowResponse)
9495getLastNPostsQ lim = getPostQ
95− (limit lim . orderBy [#posts ! #postRowId & Desc]) id
96+ (limit lim . orderBy [#posts ! #postRowUpdateTime & Desc]) id
9697
9798getLastNPostsForUserQ :: Limit -> Query Schema (TuplePG (Only UserId)) (RowPG PostRowResponse)
9899getLastNPostsForUserQ lim = getPostQ
99− (limit lim . orderBy [#posts ! #postRowId & Desc])
100+ (limit lim . orderBy [#posts ! #postRowUpdateTime & Desc])
100101 (where_ $ #postRowAuthorId .== param @1)
101102
102103createPostRowQ :: Manipulation Schema (TuplePG (Only UserId)) (RowPG (Only PostId))
103104createPostRowQ = insertRow #posts
104− (Default `as` #postRowId :* Set (param @1) `as` #postRowAuthorId)
105+ (Default `as` #postRowId :*
106+ Set (param @1) `as` #postRowAuthorId :*
107+ Set currentTimestamp `as` #postRowUpdateTime)
105108 OnConflictDoRaise
106109 (Returning $ #postRowId `as` #fromOnly)
107110
108111createPostElementRowsQ :: Manipulation Schema (TuplePG (PostElementRow Post)) '[]
109112createPostElementRowsQ = insertRow_ #postElements
110113 (Set (param @1) `as` #rowElementId :*
111− Set (param @2) `as` #rowElementAuthorId :*
112− Set (param @3) `as` #rowElementOrd :*
113− Set (param @4) `as` #rowElementMarkdown :*
114− Set (param @5) `as` #rowElementLatex :*
115− Set (param @6) `as` #rowElementImage :*
116− Set (param @7) `as` #rowElementQuote :*
117− Set (param @8) `as` #rowElementAttachment)
114+ Set (param @2) `as` #rowElementOrd :*
115+ Set (param @3) `as` #rowElementMarkdown :*
116+ Set (param @4) `as` #rowElementLatex :*
117+ Set (param @5) `as` #rowElementImage :*
118+ Set (param @6) `as` #rowElementQuote :*
119+ Set (param @7) `as` #rowElementAttachment)
118120
119121-- MARK: FrontEnd functions
120122
denis/src/Data/Schema.hs+4−10
@@ -30,7 +30,8 @@ type Schema =
3030 "fk_author_id" ::: 'ForeignKey '["postRowAuthorId"] "users" '["userId"]] :=>
3131 '[
3232 "postRowId" ::: 'Def :=> 'NotNull 'PGint8,
33− "postRowAuthorId" ::: 'NoDef :=> 'NotNull 'PGint8
33+ "postRowAuthorId" ::: 'NoDef :=> 'NotNull 'PGint8,
34+ "postRowUpdateTime" ::: 'NoDef :=> 'NotNull 'PGtimestamptz
3435 ]),
3536 "quotes" ::: 'Table (
3637 '[
@@ -43,14 +44,12 @@ type Schema =
4344 "postElements" ::: 'Table (
4445 '[
4546 "fk_post_quote_self_id" ::: 'ForeignKey '["rowElementId"] "posts" '["postRowId"],
46− "fk_post_element_user_id" ::: 'ForeignKey '["rowElementAuthorId"] "users" '["userId"],
4747 "fk_post_quote_id" ::: 'ForeignKey '["rowElementQuote"] "quotes" '["quoteRowId"]
4848 -- ,
4949 -- "unique_post_quote" ::: 'Check '["rowElementOrd", "rowElementMarkdown", "rowElementLatex", "rowElementImage", "rowElementQuote", "rowElementAttachment"]
5050 ] :=>
5151 '[
5252 "rowElementId" ::: 'NoDef :=> 'NotNull 'PGint8,
53− "rowElementAuthorId" ::: 'NoDef :=> 'NotNull 'PGint8,
5453 "rowElementOrd" ::: 'NoDef :=> 'NotNull 'PGint8,
5554 "rowElementMarkdown" ::: 'NoDef :=> 'Null 'PGtext,
5655 "rowElementLatex" ::: 'NoDef :=> 'Null 'PGtext,
@@ -61,14 +60,12 @@ type Schema =
6160 "quoteElements" ::: 'Table (
6261 '[
6362 "fk_quotes_quote_self_id" ::: 'ForeignKey '["rowElementId"] "quotes" '["quoteRowId"],
64− "fk_quote_element_user_id" ::: 'ForeignKey '["rowElementAuthorId"] "users" '["userId"],
6563 "fk_quote_quote_id" ::: 'ForeignKey '["rowElementQuote"] "quotes" '["quoteRowId"]
6664 -- ,
6765 -- "unique_quote_quote" ::: 'Check '["rowElementOrd", "rowElementMarkdown", "rowElementLatex", "rowElementImage", "rowElementQuote", "rowElementAttachment"]
6866 ] :=>
6967 '[
7068 "rowElementId" ::: 'NoDef :=> 'NotNull 'PGint8,
71− "rowElementAuthorId" ::: 'NoDef :=> 'NotNull 'PGint8,
7269 "rowElementOrd" ::: 'NoDef :=> 'NotNull 'PGint8,
7370 "rowElementMarkdown" ::: 'NoDef :=> 'Null 'PGtext,
7471 "rowElementLatex" ::: 'NoDef :=> 'Null 'PGtext,
@@ -101,7 +98,8 @@ createTables = createTable #users (
10198 primaryKey #userId `as` #pk_users
10299 ) >>> createTable #posts (
103100 serial8 `as` #postRowId :*
104− notNullable int8 `as` #postRowAuthorId
101+ notNullable int8 `as` #postRowAuthorId :*
102+ notNullable timestampWithTimeZone `as` #postRowUpdateTime
105103 ) (
106104 primaryKey #postRowId `as` #pk_posts :*
107105 foreignKey #postRowAuthorId #users #userId OnDeleteCascade OnUpdateCascade `as` #fk_author_id
@@ -113,7 +111,6 @@ createTables = createTable #users (
113111 foreignKey #quoteRowPostId #posts #postRowId OnDeleteCascade OnUpdateCascade `as` #fk_quote_post_id
114112 ) >>> createTable #postElements (
115113 notNullable int8 `as` #rowElementId :*
116− notNullable int8 `as` #rowElementAuthorId :*
117114 notNullable int8 `as` #rowElementOrd :*
118115 nullable text `as` #rowElementMarkdown :*
119116 nullable text `as` #rowElementLatex :*
@@ -122,11 +119,9 @@ createTables = createTable #users (
122119 nullable text `as` #rowElementAttachment
123120 ) (
124121 foreignKey #rowElementId #posts #postRowId OnDeleteCascade OnUpdateCascade `as` #fk_post_quote_self_id :*
125− foreignKey #rowElementAuthorId #users #userId OnDeleteCascade OnUpdateCascade `as` #fk_post_element_user_id :*
126122 foreignKey #rowElementQuote #quotes #quoteRowId OnDeleteCascade OnUpdateCascade `as` #fk_post_quote_id
127123 ) >>> createTable #quoteElements (
128124 notNullable int8 `as` #rowElementId :*
129− notNullable int8 `as` #rowElementAuthorId :*
130125 notNullable int8 `as` #rowElementOrd :*
131126 nullable text `as` #rowElementMarkdown :*
132127 nullable text `as` #rowElementLatex :*
@@ -135,7 +130,6 @@ createTables = createTable #users (
135130 nullable text `as` #rowElementAttachment
136131 ) (
137132 foreignKey #rowElementId #quotes #quoteRowId OnDeleteCascade OnUpdateCascade `as` #fk_quotes_quote_self_id :*
138− foreignKey #rowElementAuthorId #users #userId OnDeleteCascade OnUpdateCascade `as` #fk_quote_element_user_id :*
139133 foreignKey #rowElementQuote #quotes #quoteRowId OnDeleteCascade OnUpdateCascade `as` #fk_quote_quote_id
140134 -- ) >>> createView #postsView (select (
141135 -- #posts ! #postRowId :*
denis/src/Server/API.hs+2−6
@@ -16,7 +16,6 @@ import Data.Proxy
1616import Servant.API
1717import Data.User
1818import Server.Auth
19−import Data.Int ()
2019import Servant.Server
2120import Data.Connection
2221import Data.Query
@@ -32,6 +31,7 @@ instance HasDocs api => HasDocs (Authentication :> api) where
3231 docsFor Proxy (endpoint, action) =
3332 docsFor (Proxy :: Proxy api) (endpoint, action & notes <>~ [DocNote "Authentication" ["This method requires cookies set in the `POST /authenticate` method.\n\nReturns error `401 Unauthorized` if the cookies are invalid or don't premit access to the requested data."]])
3433
34+
3535-- MARK: Implementation
3636
3737type Authentication = AuthProtect "basicAuth"
@@ -53,8 +53,4 @@ mkServerAPI l =
5353 authenticate :<|> (\uId ->
5454 mapM (runQnotFound . getUser) :<|>
5555 postApi uId
56− )
57−
58−-- getPostsS :: [UserId] -> App [User]
59−-- getPostsS = mapM getPost
60−
56+ )