From f8a4775bcce011148ef8e8337b96b8a79bf0ecec Mon Sep 17 00:00:00 2001 From: EliasSchriefer Date: Sun, 19 Dec 2021 01:05:13 +0100 Subject: [PATCH] Add retrieving limited number of messages Optional `lastMsg` now works by getting all messages with a newer timestamp than the reference message. Optional `limit` works using SQL ~magic~ keyword `LIMIT`. Also `limit` has to be at least 1. --- src/graphql.rs | 36 ++++++++++++++++++++++++++++++++++-- test-api.sh | 23 +++++++++++++++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/graphql.rs b/src/graphql.rs index 3c3968b..47b4754 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -610,14 +610,46 @@ impl Query { Ok(chats) } - async fn getMessages(context: &Context, user: ID, password_hash: String, chat: ID, last_msg: Option) -> FieldResult> { + async fn getMessages(context: &Context, user: ID, password_hash: String, chat: ID, last_msg: Option, limit: Option) -> FieldResult> { + let limit = match limit { + Some(l) if l < 1 => Err("limit cannot be negative or 0".to_string())?, + Some(l) => Some(l as u32), + None => None, + }; + let user = id_to_uuid(&user)?.to_simple(); user_authentication(&context.db, &user, &password_hash).await?; + let chat = id_to_uuid(&chat)?.to_simple(); + + let last_msg_timestamp = if let Some(last_msg) = last_msg { + Some( + sqlx::query(format!( + r#"SELECT timestamp FROM msgdata_{} WHERE msg_id = "{}""#, + chat, + id_to_uuid(&last_msg)?.to_simple(), + ).as_str()) + .fetch_one(&context.db).await? + .try_get::("timestamp")? as u128 + ) + } else { + None + }; + let mut messages = Vec::new(); for message in sqlx::query(format!( - r#"SELECT * FROM msgdata_{} ORDER BY timestamp DESC"#, + r#"SELECT * FROM msgdata_{} {} ORDER BY timestamp DESC {}"#, chat, + if let Some(last_msg_timestamp) = last_msg_timestamp { + format!("WHERE timestamp > {}", last_msg_timestamp) + } else { + String::new() + }, + if let Some(limit) = limit { + format!("LIMIT {}", limit) + } else { + String::new() + }, ).as_str()).fetch_all(&context.db).await? { messages.push(Message { id: ID::from(message.try_get::("msg_id")?), diff --git a/test-api.sh b/test-api.sh index f9d5d3c..53735e0 100755 --- a/test-api.sh +++ b/test-api.sh @@ -19,8 +19,27 @@ abc=$(echo "$chatIDs" | jq -r .aGroupChats[0].id) echo echo Send a private/group message: -curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"mutation sendMessages(\$a: ID!, \$pwHash: String!, \$bChat: ID!, \$abc: ID!, \$msg: MessageInput!) {\n chat: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$bChat, msg: \$msg)\n group: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$abc, msg: \$msg)\n}\",\"variables\":{\"pwHash\":\"1234567890\",\"a\":\"$a\",\"bChat\":\"$ab\",\"abc\":\"$abc\",\"msg\":{\"msgType\":\"TEXT\",\"content\":\"Test\"}},\"operationName\":\"sendMessages\"}" | jq . +sentMessageIDs=$(curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"mutation sendMessages(\$a: ID!, \$pwHash: String!, \$bChat: ID!, \$abc: ID!, \$msg: MessageInput!) {\n chat: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$bChat, msg: \$msg)\n group: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$abc, msg: \$msg)\n}\",\"variables\":{\"pwHash\":\"1234567890\",\"a\":\"$a\",\"bChat\":\"$ab\",\"abc\":\"$abc\",\"msg\":{\"msgType\":\"TEXT\",\"content\":\"Test\"}},\"operationName\":\"sendMessages\"}" | jq .data) +echo "$sentMessageIDs" | jq . +lastChatMsg=$(echo "$sentMessageIDs" | jq -r .chat) +lastGroupChatMsg=$(echo "$sentMessageIDs" | jq -r .group) echo echo Get private/group messages: -curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"query getMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!) {\n chat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$chat) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n groupChat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$groupChat) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\"},\"operationName\":\"getMessages\"}" | jq .data \ No newline at end of file +curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"query getMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!) {\n chat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$chat) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n groupChat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$groupChat) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\"},\"operationName\":\"getMessages\"}" | jq .data + +echo +echo Send a new private/group message: +curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"mutation sendNewMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!, \$msg: MessageInput!) {\n chat: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$chat, msg: \$msg)\n group: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$groupChat, msg: \$msg)\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\",\"msg\":{\"msgType\":\"TEXT\",\"content\":\"New Message!\"}},\"operationName\":\"sendNewMessages\"}" | jq .data + +echo +echo Send a second new private/group message: +curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"mutation sendNewMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!, \$msg: MessageInput!) {\n chat: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$chat, msg: \$msg)\n group: sendMessage(user: \$a, passwordHash: \$pwHash, chat: \$groupChat, msg: \$msg)\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\",\"msg\":{\"msgType\":\"TEXT\",\"content\":\"New Message!\"}},\"operationName\":\"sendNewMessages\"}" | jq .data + +echo +echo Get new private/group messages: +curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"query getMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!, \$lastChatMsg: ID!, \$lastGroupChatMsg: ID!) {\n chat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$chat, lastMsg: \$lastChatMsg) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n groupChat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$groupChat, lastMsg: \$lastGroupChatMsg) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\",\"lastChatMsg\":\"$lastChatMsg\",\"lastGroupChatMsg\":\"$lastGroupChatMsg\"},\"operationName\":\"getMessages\"}" | jq .data + +echo +echo Get new private/group messages with a limit of 1: +curl "localhost:8080/graphql" -X POST -H "content-type: application/json" --data "{\"query\":\"query getMessages(\$a: ID!, \$pwHash: String!, \$chat: ID!, \$groupChat: ID!, \$lastChatMsg: ID!, \$lastGroupChatMsg: ID!, \$limit: Int) {\n chat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$chat, lastMsg: \$lastChatMsg, limit: \$limit) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n groupChat: getMessages(user: \$a, passwordHash: \$pwHash, chat: \$groupChat, lastMsg: \$lastGroupChatMsg, limit: \$limit) {\n id\n timestamp\n sender\n msgType\n content\n hideFor\n seenBy\n }\n}\",\"variables\":{\"a\":\"$a\",\"pwHash\":\"1234567890\",\"chat\":\"$ab\",\"groupChat\":\"$abc\",\"lastChatMsg\":\"$lastChatMsg\",\"lastGroupChatMsg\":\"$lastGroupChatMsg\",\"limit\":1},\"operationName\":\"getMessages\"}" | jq .data