[fractal/backend: 5/9] backend: Room and Message relation in database
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/backend: 5/9] backend: Room and Message relation in database
- Date: Wed, 30 Jan 2019 11:53:42 +0000 (UTC)
commit c32af3c4c70eea85917f510d62fcae28a53601c5
Author: Daniel GarcĂa Moreno <danigm wadobo com>
Date: Mon Dec 24 18:04:01 2018 +0100
backend: Room and Message relation in database
fractal-backend/src/model/message.rs | 51 ++++++++++++++++++++++++++++++++++--
fractal-backend/src/model/mod.rs | 1 +
fractal-backend/tests/models.rs | 48 +++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 2 deletions(-)
---
diff --git a/fractal-backend/src/model/message.rs b/fractal-backend/src/model/message.rs
index 1ece037e..30a7abd8 100644
--- a/fractal-backend/src/model/message.rs
+++ b/fractal-backend/src/model/message.rs
@@ -50,7 +50,6 @@ impl Model for Message {
}
fn create_sql() -> String {
- //TODO: implements relation to room as ForeignKey
format!(
"
CREATE TABLE if not exists {} (
@@ -68,7 +67,9 @@ impl Model for Message {
receipt TEXT NOT NULL,
redacted BOOLEAN NOT NULL,
in_reply_to TEXT,
- extra_content TEXT
+ extra_content TEXT,
+
+ FOREIGN KEY(room) REFERENCES room(id)
)
",
Self::table_name()
@@ -151,3 +152,49 @@ impl Model for Message {
}
}
}
+
+pub trait MessageModel: Sized {
+ fn get_range(room: &str, limit: Option<u32>, offset: Option<u32>) -> Result<Vec<Self>, Error>;
+}
+
+impl MessageModel for Message {
+ /// Returns a list of Messages from filtering by `room` roomid ordered by
+ /// date
+ ///
+ /// The param `limit` defines the number of messages to return, if it's
+ /// None, all messages will be returned
+ ///
+ /// The param `offset` is used to ignore that number of messages and start
+ /// to return from that. if it's None, the return will be done from the end
+ /// of the list.
+ fn get_range(room: &str, limit: Option<u32>, offset: Option<u32>) -> Result<Vec<Self>, Error> {
+ let fields = Self::fields().join(",");
+ let mut query = format!(
+ "SELECT {} FROM {} WHERE room = ? ORDER BY date desc",
+ fields,
+ Self::table_name()
+ );
+
+ if let Some(l) = limit {
+ query = query + &format!(" LIMIT {}", l);
+ }
+
+ if let Some(o) = offset {
+ query = query + &format!(" OFFSET {}", o);
+ }
+
+ conn(
+ move |c| {
+ let mut stmt = c.prepare(&query)?;
+ let iter = stmt.query_map(&[room], Self::map_row)?;
+
+ let array = iter
+ .filter(|r| r.is_ok())
+ .map(|r| r.unwrap())
+ .collect::<Vec<Self>>();
+ Ok(array)
+ },
+ Err(err_msg("Connection not init")),
+ )
+ }
+}
diff --git a/fractal-backend/src/model/mod.rs b/fractal-backend/src/model/mod.rs
index 22ba84a4..2864fd87 100644
--- a/fractal-backend/src/model/mod.rs
+++ b/fractal-backend/src/model/mod.rs
@@ -8,6 +8,7 @@ pub mod message;
pub mod room;
pub use self::message::Message;
+pub use self::message::MessageModel;
pub use self::room::Room;
pub trait Model: Sized {
diff --git a/fractal-backend/tests/models.rs b/fractal-backend/tests/models.rs
index faf8c5b4..4289f088 100644
--- a/fractal-backend/tests/models.rs
+++ b/fractal-backend/tests/models.rs
@@ -1,10 +1,14 @@
+extern crate chrono;
extern crate fractal_backend;
use fractal_backend::init_local as init;
use fractal_backend::model::Message;
+use fractal_backend::model::MessageModel;
use fractal_backend::model::Model;
use fractal_backend::model::Room;
+use chrono::prelude::*;
+
#[test]
fn room_model() {
let _ = init("").unwrap();
@@ -59,3 +63,47 @@ fn message_model() {
let really_deleted = Message::get("MSGID");
assert!(really_deleted.is_err());
}
+
+#[test]
+fn message_room_relation() {
+ let _ = init("").unwrap();
+
+ let created = Room::create_table();
+ assert!(created.is_ok());
+ let created = Message::create_table();
+ assert!(created.is_ok());
+
+ let r = Room::new("ROOM ID".to_string(), Some("ROOM NAME".to_string()));
+ let stored = r.store();
+ assert!(stored.is_ok());
+
+ let mut msg = Message::default();
+ msg.room = r.id.clone();
+
+ for i in 0..100 {
+ msg.id = Some(format!("MSG {}", i));
+ msg.date = Local.ymd(1970, 1, 1).and_hms(0, i / 60, i % 60);
+ let _ = msg.store();
+ }
+
+ msg.room = "ROOM ID 2".to_string();
+ for i in 0..100 {
+ msg.id = Some(format!("MSG ROOM2 {}", i));
+ msg.date = Local.ymd(1970, 1, 1).and_hms(0, i / 60, i % 60);
+ let _ = msg.store();
+ }
+
+ for i in 0..10 {
+ let items = Message::get_range(&r.id, Some(10), Some(i * 10)).unwrap();
+ for (j, m) in items.iter().enumerate() {
+ let idx = 99 - (10 * i as usize + j);
+ assert_eq!(m.id, Some(format!("MSG {}", idx)));
+ }
+ }
+
+ let items = Message::get_range(&r.id, Some(10), Some(95)).unwrap();
+ assert_eq!(items.len(), 5);
+
+ let items = Message::get_range(&r.id, Some(10), Some(100)).unwrap();
+ assert_eq!(items.len(), 0);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]