forked from lavina/lavina
persistence of chat messages
This commit is contained in:
parent
f401aa786e
commit
5c07c8368d
|
@ -30,3 +30,22 @@ Make sure `xmpp.key` starts and ends with:
|
|||
XMPP XSDs - [https://xmpp.org/schemas/index.shtml]
|
||||
|
||||
IRC modern spec - [https://modern.ircdocs.horse/]
|
||||
|
||||
## Initializing DB with some users
|
||||
|
||||
sqlite3 db.sqlite < test/init_state.sql
|
||||
|
||||
Same test migration could be used for integration tests in the future.
|
||||
|
||||
## Using irssi
|
||||
|
||||
irssi in a TUI-based IRC client.
|
||||
|
||||
Connecting:
|
||||
|
||||
/connect -nocap <address> [<port> [<password> [<nick>]]]
|
||||
|
||||
Password should be the same as in storage.
|
||||
Example:
|
||||
|
||||
/connect -nocap 127.0.0.1 6667 parolchik1 kek
|
|
@ -61,9 +61,9 @@ impl Storage {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub async fn create_new_room(&mut self, name: &str, topic: &str) -> Result<()> {
|
||||
pub async fn create_new_room(&mut self, name: &str, topic: &str) -> Result<u32> {
|
||||
let mut executor = self.conn.lock().await;
|
||||
let _: (u32,) = sqlx::query_as(
|
||||
let (id,): (u32,) = sqlx::query_as(
|
||||
"insert into rooms(name, topic)
|
||||
values (?, ?)
|
||||
returning id;",
|
||||
|
@ -73,6 +73,23 @@ impl Storage {
|
|||
.fetch_one(&mut *executor)
|
||||
.await?;
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub async fn insert_message(&mut self, room_id: u32, id: u32, content: &str) -> Result<()> {
|
||||
let mut executor = self.conn.lock().await;
|
||||
let (_,): (u32,) = sqlx::query_as(
|
||||
"insert into messages(room_id, id, content)
|
||||
values (?, ?, ?);
|
||||
update rooms set message_count = message_count + 1 where id = ?;",
|
||||
)
|
||||
.bind(room_id)
|
||||
.bind(id)
|
||||
.bind(content)
|
||||
.bind(room_id)
|
||||
.fetch_one(&mut *executor)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -63,10 +63,12 @@ impl RoomRegistry {
|
|||
// room exists, but was not loaded
|
||||
log::debug!("Loading room {}...", &room_id.0);
|
||||
let room = Room {
|
||||
storage_id: stored_room.id,
|
||||
room_id: room_id.clone(),
|
||||
subscriptions: HashMap::new(),
|
||||
subscriptions: HashMap::new(), // TODO figure out how to populate subscriptions
|
||||
topic: stored_room.topic.into(),
|
||||
message_count: stored_room.message_count,
|
||||
storage: inner.storage.clone(),
|
||||
};
|
||||
let room_handle = RoomHandle(Arc::new(AsyncRwLock::new(room)));
|
||||
inner.rooms.insert(room_id, room_handle.clone());
|
||||
|
@ -76,12 +78,14 @@ impl RoomRegistry {
|
|||
// room does not exist, create it and load
|
||||
log::debug!("Creating room {}...", &room_id.0);
|
||||
let topic = "New room";
|
||||
let _ = inner.storage.create_new_room(&*room_id.0, &*topic).await?;
|
||||
let id = inner.storage.create_new_room(&*room_id.0, &*topic).await?;
|
||||
let room = Room {
|
||||
storage_id: id,
|
||||
room_id: room_id.clone(),
|
||||
subscriptions: HashMap::new(),
|
||||
topic: topic.into(),
|
||||
message_count: 0,
|
||||
storage: inner.storage.clone(),
|
||||
};
|
||||
let room_handle = RoomHandle(Arc::new(AsyncRwLock::new(room)));
|
||||
inner.rooms.insert(room_id, room_handle.clone());
|
||||
|
@ -135,7 +139,7 @@ impl RoomHandle {
|
|||
}
|
||||
|
||||
pub async fn send_message(&self, player_id: PlayerId, body: Str) {
|
||||
let lock = self.0.read().await;
|
||||
let mut lock = self.0.write().await;
|
||||
lock.send_message(player_id, body).await;
|
||||
}
|
||||
|
||||
|
@ -164,10 +168,12 @@ impl RoomHandle {
|
|||
}
|
||||
|
||||
struct Room {
|
||||
storage_id: u32,
|
||||
room_id: RoomId,
|
||||
subscriptions: HashMap<PlayerId, PlayerHandle>,
|
||||
message_count: u32,
|
||||
topic: Str,
|
||||
storage: Storage,
|
||||
}
|
||||
impl Room {
|
||||
async fn add_subscriber(&mut self, player_id: PlayerId, player_handle: PlayerHandle) {
|
||||
|
@ -180,14 +186,17 @@ impl Room {
|
|||
self.broadcast_update(update, &player_id).await;
|
||||
}
|
||||
|
||||
async fn send_message(&self, author_id: PlayerId, body: Str) {
|
||||
async fn send_message(&mut self, author_id: PlayerId, body: Str) -> Result<()> {
|
||||
tracing::info!("Adding a message to room");
|
||||
self.storage.insert_message(self.storage_id, self.message_count, &body).await?;
|
||||
self.message_count += 1;
|
||||
let update = Updates::NewMessage {
|
||||
room_id: self.room_id.clone(),
|
||||
author_id: author_id.clone(),
|
||||
body,
|
||||
};
|
||||
self.broadcast_update(update, &author_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn broadcast_update(&self, update: Updates, except: &PlayerId) {
|
||||
|
|
Loading…
Reference in New Issue