pref: Sort messages within Cassandra

This commit is contained in:
April Hall 2025-01-13 08:29:47 -05:00
parent 4fc96f4d40
commit d3b8653c88
No known key found for this signature in database
GPG Key ID: A49AC35CB186266C
3 changed files with 24 additions and 17 deletions

View File

@ -1,14 +1,29 @@
import cassandra from 'cassandra-driver'; import cassandra from 'cassandra-driver';
function reverseArray(array: cassandra.types.Row[]) {
let left = null;
let right = null;
const length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
const temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
async function createChannel(client: cassandra.Client, channelName: string) { async function createChannel(client: cassandra.Client, channelName: string) {
try { try {
await client.execute(` await client.execute(`
CREATE TABLE IF NOT EXISTS channels.channel_${channelName} ( CREATE TABLE IF NOT EXISTS channels.channel_${channelName} (
id UUID PRIMARY KEY, id UUID,
message_content TEXT, message_content TEXT,
channel_name TEXT,
timestamp TIMESTAMP, timestamp TIMESTAMP,
sender UUID sender UUID,
);`); PRIMARY KEY (channel_name, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);`);
} catch (e) { } catch (e) {
// @ts-expect-error I don't like this thing yelling at me // @ts-expect-error I don't like this thing yelling at me
console.log(`Error creating new channel: ${e.message}`); console.log(`Error creating new channel: ${e.message}`);
@ -18,8 +33,8 @@ async function createChannel(client: cassandra.Client, channelName: string) {
async function storeMessage(client: cassandra.Client, channelName: string, content: string, sender: string, id: string) { async function storeMessage(client: cassandra.Client, channelName: string, content: string, sender: string, id: string) {
try { try {
const now = new Date(); const now = new Date();
await client.execute(`INSERT INTO channels.channel_${channelName} (id, message_content, timestamp, sender) await client.execute(`INSERT INTO channels.channel_${channelName} (id, message_content, channel_name, timestamp, sender)
VALUES (${id}, '${content}', ${now.getTime()}, ${sender})`); VALUES (${id}, '${content}', '${channelName}', ${now.getTime()}, ${sender})`);
} catch (e) { } catch (e) {
// @ts-expect-error I don't like this thing yelling at me // @ts-expect-error I don't like this thing yelling at me
console.log(`Error storing messages: ${e.message}`); console.log(`Error storing messages: ${e.message}`);
@ -28,16 +43,8 @@ async function storeMessage(client: cassandra.Client, channelName: string, conte
async function getMessages(client: cassandra.Client, channelName: string, limit: number) { async function getMessages(client: cassandra.Client, channelName: string, limit: number) {
try { try {
const res = await client.execute(`SELECT * FROM channels.channel_${channelName}`); const res = await client.execute(`SELECT * FROM channels.channel_${channelName} WHERE channel_name = '${channelName}' ORDER BY timestamp DESC LIMIT ${limit}`);
// We have to sort the rows within the function instead of an ORDER BY return reverseArray(res.rows)
// because of a limitation within Cassandra requiring a partition key
// to be specified by EQ or IN when using ORDER BY
res.rows.sort((a, b) => a.timestamp - b.timestamp);
// For the same reason as above, we have to apply the limit manually
// as well, because if we only query 5, but they're not properly sorted,
// it will only return the first 5 instead of the last 5
return res.rows.slice(-limit);
} catch (e) { } catch (e) {
// @ts-expect-error I don't like this thing yelling at me // @ts-expect-error I don't like this thing yelling at me
console.log(`Error fetching messages: ${e.message}`); console.log(`Error fetching messages: ${e.message}`);

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import '$lib/app.css'; import '../app.css';
let { children } = $props(); let { children } = $props();
</script> </script>

View File

@ -1,6 +1,6 @@
import type { PageLoad } from './$types'; import type { PageLoad } from './$types';
import type { TypeMessage } from '$lib'; import type { TypeMessage } from '$lib';
import { getMessages, client } from '$/lib/server/db'; import { getMessages, client } from '$lib/server/db';
export const load: PageLoad = async () => { export const load: PageLoad = async () => {
const rows = await getMessages(client, '000', 5); const rows = await getMessages(client, '000', 5);