fix likes queries

This commit is contained in:
me 2024-11-09 00:20:52 +02:00
parent 2187e44c5b
commit 3a7ae4bb96
4 changed files with 104 additions and 79 deletions

168
app/DB.hs
View file

@ -29,6 +29,7 @@ data DB
, getNote :: DB.Int64 -> IO (Maybe Note) , getNote :: DB.Int64 -> IO (Maybe Note)
, insertNote :: NoteEntry -> IO (DB.Int64, Note) , insertNote :: NoteEntry -> IO (DB.Int64, Note)
, insertLike :: LikeEntry -> IO DB.Int64 , insertLike :: LikeEntry -> IO DB.Int64
-- , deleteLike :: LikeEntry -> IO (Maybe DB.Int64)
, insertFollower , insertFollower
:: forall a :: forall a
. (Typeable a) => FollowerEntry -> (DB.Int64 -> IO a) -> IO a . (Typeable a) => FollowerEntry -> (DB.Int64 -> IO a) -> IO a
@ -184,13 +185,14 @@ migrateDown = \case
-- * Database actions -- * Database actions
getNotesFromDb :: DB.SQLite [Note] getNotesFromDb :: DB.SQLite [Note]
getNotesFromDb = getNotesFromDb = do
map (snd . decodeNoteRow) <$> uncurry DB.runWith getNotesSQL result <- uncurry DB.runWith getNotesSQL
pure $ map (snd . decodeNoteRow) result
getNoteFromDb :: DB.Int64 -> DB.SQLite (Maybe Note) getNoteFromDb :: DB.Int64 -> DB.SQLite (Maybe Note)
getNoteFromDb noteid = do getNoteFromDb noteid = do
n <- map (snd . decodeNoteRow) <$> uncurry DB.runWith (getNoteSQL noteid) result <- uncurry DB.runWith (getNoteSQL noteid)
pure (listToMaybe n) pure $ listToMaybe $ map (snd . decodeNoteRow) result
insertNoteToDb :: Url -> NoteEntry -> DB.SQLite (DB.Int64, Note) insertNoteToDb :: Url -> NoteEntry -> DB.SQLite (DB.Int64, Note)
insertNoteToDb actor note = do insertNoteToDb actor note = do
@ -222,48 +224,55 @@ getNotesSQL :: (DB.SQL, [DB.SQLData])
getNotesSQL = getNotesSQL =
( [r| ( [r|
SELECT SELECT
id as nid, note_id,
actor || '/notes/' || id, note_url_id,
published, published,
actor, note_actor,
content, note_content,
name, note_name,
inReplyTo, note_inReplyTo,
url, note_url,
json_group_array(like) FILTER (WHERE like IS NOT NULL) as likes
json_group_array(
json_object(
'likeId',
like_id,
'likeUrl',
like_url,
'likeActorUrl',
like_actor_url,
'likeNoteUrl',
like_note_url
)
) FILTER (WHERE like_id IS NOT NULL) as likes
FROM FROM
( SELECT ( SELECT
note.*, note.id as note_id,
CASE note.url_id as note_url_id,
WHEN like.id IS NOT NULL note.published as published,
THEN json_object( note.actor as note_actor,
'likeId', note.content as note_content,
like.id, note.name as note_name,
'likeUrl', note.inReplyTo as note_inReplyTo,
like.like_url, note.url as note_url,
'likeActorUrl',
like.actor_url, like.id as like_id,
'likeNoteUrl', like.like_url as like_url,
like.note_url like.actor_url as like_actor_url,
) like.note_url as like_note_url
ELSE NULL
END AS like
FROM FROM
( SELECT * FROM note ( SELECT
*,
actor || '/notes/' || id as url_id
FROM note
WHERE inReplyTo IS NULL WHERE inReplyTo IS NULL
) as note ) as note
LEFT JOIN like LEFT JOIN like
ON note.url = like.note_url ON note.url_id = like.note_url
) )
GROUP BY GROUP BY note_id
id,
actor,
published,
actor,
content,
name,
inReplyTo,
url
ORDER BY published DESC ORDER BY published DESC
|] |]
, [] , []
@ -273,45 +282,55 @@ getNoteSQL :: DB.Int64 -> (DB.SQL, [DB.SQLData])
getNoteSQL noteid = getNoteSQL noteid =
( [r| ( [r|
SELECT SELECT
id as nid, note_id,
actor || '/notes/' || id, note_url_id,
published, published,
actor, note_actor,
content, note_content,
name, note_name,
inReplyTo, note_inReplyTo,
url, note_url,
json_group_array(like) FILTER (WHERE like IS NOT NULL) as likes
json_group_array(
json_object(
'likeId',
like_id,
'likeUrl',
like_url,
'likeActorUrl',
like_actor_url,
'likeNoteUrl',
like_note_url
)
) FILTER (WHERE like_id IS NOT NULL) as likes
FROM FROM
( SELECT ( SELECT
note.*, note.id as note_id,
CASE note.url_id as note_url_id,
WHEN like.id IS NOT NULL note.published as published,
THEN json_object( note.actor as note_actor,
'likeId', note.content as note_content,
like.id, note.name as note_name,
'likeUrl', note.inReplyTo as note_inReplyTo,
like.like_url, note.url as note_url,
'likeActorUrl',
like.actor_url, like.id as like_id,
'likeNoteUrl', like.like_url as like_url,
like.note_url like.actor_url as like_actor_url,
) like.note_url as like_note_url
ELSE NULL
END AS like FROM
FROM (SELECT * FROM note WHERE id = ?) as note ( SELECT
*,
actor || '/notes/' || id as url_id
FROM note WHERE id = ?
) as note
LEFT JOIN like LEFT JOIN like
ON note.url = like.note_url ON note.url_id = like.note_url
) )
GROUP BY GROUP BY
id, note_id
actor,
published,
actor,
content,
name,
inReplyTo,
url
|] |]
, [DB.SQLInteger noteid] , [DB.SQLInteger noteid]
) )
@ -344,13 +363,10 @@ insertNoteSQL actor note =
insertLikeSQL :: LikeEntry -> (DB.SQL, [DB.SQLData]) insertLikeSQL :: LikeEntry -> (DB.SQL, [DB.SQLData])
insertLikeSQL like = insertLikeSQL like =
( [r| ( [r|
INSERT INTO outer_like(like_url, actor_url, note_url) INSERT INTO like(like_url, actor_url, note_url)
VALUES (?, ?, ?) VALUES (?, ?, ?)
RETURNING RETURNING
id as id, id as id
like_url,
actor_url,
note_url
|] |]
, [ DB.SQLText (T.pack like.likeUrl) , [ DB.SQLText (T.pack like.likeUrl)
, DB.SQLText (T.pack like.likeActorUrl.unwrap) , DB.SQLText (T.pack like.likeActorUrl.unwrap)

View file

@ -72,13 +72,19 @@ noteHtml note = do
H.p_ $ H.a_ [H.href_ (T.pack url)] $ fromString url H.p_ $ H.a_ [H.href_ (T.pack url)] $ fromString url
Nothing -> pure () Nothing -> pure ()
Fedi.for_ note.published \published -> Fedi.for_ note.published \published -> do
H.a_ H.a_
[ H.href_ noteid [ H.href_ noteid
, H.class_ "note-time" , H.class_ "note-time"
, H.title_ "See note page" , H.title_ "See note page"
] ]
(H.span_ [H.class_ $ "note-date-published"] $ H.toHtml (show published)) (H.span_ [H.class_ $ "note-date-published"] $ H.toHtml (show published))
let numberOfLikes = length $ Fedi.noteLikes note
Fedi.when (numberOfLikes > 0) do
H.div_ do
H.toHtml (show numberOfLikes)
" "
""
H.div_ [H.class_ $ "note-content " <> checkDirection (maybe "" id note.content)] $ do H.div_ [H.class_ $ "note-content " <> checkDirection (maybe "" id note.content)] $ do
H.toHtmlRaw (maybe "" id note.content) H.toHtmlRaw (maybe "" id note.content)

View file

@ -14,8 +14,8 @@ acceptRequest
-> IO () -> IO ()
acceptRequest details actor activity operation = do acceptRequest details actor activity operation = do
_ <- liftIO $ Async.async do _ <- liftIO $ Async.async do
Log.logDebug "Waiting 10 seconds before accepting follow..." Log.logDebug "Waiting 1 second before accepting follow..."
threadDelay 10000000 -- 10 seconds threadDelay 1000000 -- 1 second
let let
callback = callback =
( \(opid :: DB.Int64) -> do ( \(opid :: DB.Int64) -> do

View file

@ -194,3 +194,6 @@ typeActivityLike actor object =
, target = Nothing , target = Nothing
, origin = Nothing , origin = Nothing
} }
noteLikes :: Note -> [Like]
noteLikes note = note.otype.likes.otype.ctype.items