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.
This commit is contained in:
Elias Schriefer 2021-12-19 01:05:13 +01:00
parent c71621b3d6
commit f8a4775bcc
2 changed files with 55 additions and 4 deletions

View File

@ -610,14 +610,46 @@ impl Query {
Ok(chats) Ok(chats)
} }
async fn getMessages(context: &Context, user: ID, password_hash: String, chat: ID, last_msg: Option<ID>) -> FieldResult<Vec<Message>> { async fn getMessages(context: &Context, user: ID, password_hash: String, chat: ID, last_msg: Option<ID>, limit: Option<i32>) -> FieldResult<Vec<Message>> {
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(); let user = id_to_uuid(&user)?.to_simple();
user_authentication(&context.db, &user, &password_hash).await?; 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::<i64, _>("timestamp")? as u128
)
} else {
None
};
let mut messages = Vec::new(); let mut messages = Vec::new();
for message in sqlx::query(format!( for message in sqlx::query(format!(
r#"SELECT * FROM msgdata_{} ORDER BY timestamp DESC"#, r#"SELECT * FROM msgdata_{} {} ORDER BY timestamp DESC {}"#,
chat, 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? { ).as_str()).fetch_all(&context.db).await? {
messages.push(Message { messages.push(Message {
id: ID::from(message.try_get::<String, _>("msg_id")?), id: ID::from(message.try_get::<String, _>("msg_id")?),

View File

@ -19,8 +19,27 @@ abc=$(echo "$chatIDs" | jq -r .aGroupChats[0].id)
echo echo
echo Send a private/group message: 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
echo Get private/group messages: 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 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