[fractal/backend: 3/9] backend: Message initial db model
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/backend: 3/9] backend: Message initial db model
- Date: Wed, 30 Jan 2019 11:53:32 +0000 (UTC)
commit d81c434bb2b73945bf69290f89996f3100ff8267
Author: Daniel García Moreno <danigm wadobo com>
Date: Thu Dec 13 16:49:56 2018 +0100
backend: Message initial db model
Cargo.lock | 2 +
fractal-backend/Cargo.toml | 2 +
fractal-backend/src/lib.rs | 2 +
fractal-backend/src/model/message.rs | 153 +++++++++++++++++++++++++++++++++++
fractal-backend/src/model/mod.rs | 3 +
fractal-backend/tests/models.rs | 23 ++++++
6 files changed, 185 insertions(+)
---
diff --git a/Cargo.lock b/Cargo.lock
index 9d16ba1e..99cf195b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -464,10 +464,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "fractal-backend"
version = "0.1.0"
dependencies = [
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"fractal-matrix-api 4.0.0",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rusqlite 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/fractal-backend/Cargo.toml b/fractal-backend/Cargo.toml
index 7d7d502c..9f5e8bc0 100644
--- a/fractal-backend/Cargo.toml
+++ b/fractal-backend/Cargo.toml
@@ -7,6 +7,8 @@ authors = ["Daniel García Moreno <danigm wadobo com>"]
rusqlite = "0.15.0"
failure = "0.1.3"
lazy_static = "1.2.0"
+serde_json = "1.0.33"
+chrono = "0.4.6"
[dependencies.fractal-matrix-api]
path = "../fractal-matrix-api"
diff --git a/fractal-backend/src/lib.rs b/fractal-backend/src/lib.rs
index 75d86d2a..41673c8e 100644
--- a/fractal-backend/src/lib.rs
+++ b/fractal-backend/src/lib.rs
@@ -1,6 +1,8 @@
+extern crate chrono;
extern crate failure;
extern crate fractal_matrix_api as api;
extern crate rusqlite;
+extern crate serde_json;
#[macro_use]
extern crate lazy_static;
diff --git a/fractal-backend/src/model/message.rs b/fractal-backend/src/model/message.rs
new file mode 100644
index 00000000..1ece037e
--- /dev/null
+++ b/fractal-backend/src/model/message.rs
@@ -0,0 +1,153 @@
+use std::collections::HashMap;
+
+pub use api::types::Message;
+use failure::err_msg;
+use failure::Error;
+
+use rusqlite::types::ToSql;
+use rusqlite::Row;
+
+use chrono::DateTime;
+use chrono::Local;
+
+use serde_json;
+use serde_json::Value;
+
+use super::conn;
+use super::Model;
+
+impl Model for Message {
+ fn table_name() -> &'static str {
+ "message"
+ }
+
+ // TODO: we need a non optional id here
+ fn get_id(&self) -> &str {
+ match self.id.as_ref() {
+ Some(r) => r,
+ None => "",
+ }
+ }
+
+ fn fields() -> Vec<&'static str> {
+ vec![
+ "sender",
+ "mtype",
+ "body",
+ "date",
+ "room",
+ "thumb",
+ "url",
+ "id",
+ "formatted_body",
+ "format",
+ "source",
+ "receipt",
+ "redacted",
+ "in_reply_to",
+ "extra_content",
+ ]
+ }
+
+ fn create_sql() -> String {
+ //TODO: implements relation to room as ForeignKey
+ format!(
+ "
+ CREATE TABLE if not exists {} (
+ sender TEXT NOT NULL,
+ mtype TEXT NOT NULL,
+ body TEXT NOT NULL,
+ date TEXT NOT NULL,
+ room TEXT NOT NULL,
+ thumb TEXT,
+ url TEXT,
+ id TEXT PRIMARY KEY,
+ formatted_body TEXT,
+ format TEXT,
+ source TEXT,
+ receipt TEXT NOT NULL,
+ redacted BOOLEAN NOT NULL,
+ in_reply_to TEXT,
+ extra_content TEXT
+ )
+ ",
+ Self::table_name()
+ )
+ }
+
+ fn store(&self) -> Result<(), Error> {
+ let fields = Self::fields().join(",");
+ let questions = Self::fields()
+ .iter()
+ .map(|_| "?")
+ .collect::<Vec<&str>>()
+ .join(",");
+ let query = format!(
+ "INSERT INTO {} ({}) VALUES ({})",
+ Self::table_name(),
+ fields,
+ questions
+ );
+
+ //TODO: maybe we should add a new table for this?
+ let receipt_serialized = serde_json::to_string(&self.receipt)?;
+ let date_serialized = serde_json::to_string(&self.date)?;
+ let extra_content = serde_json::to_string(&self.extra_content)?;
+
+ conn(
+ move |c| {
+ c.execute(
+ &query,
+ &[
+ &self.sender,
+ &self.mtype,
+ &self.body,
+ &date_serialized,
+ &self.room,
+ &self.thumb as &ToSql,
+ &self.url,
+ &self.id,
+ &self.formatted_body,
+ &self.format,
+ &self.source,
+ &receipt_serialized,
+ &self.redacted,
+ &self.in_reply_to,
+ &extra_content,
+ ],
+ )
+ .map(|_| ())
+ .map_err(|e| err_msg(e.to_string()))
+ },
+ Err(err_msg("Connection not init")),
+ )
+ }
+
+ fn map_row(row: &Row) -> Self {
+ let dstr: String = row.get(3);
+ let rstr: String = row.get(11);
+ let ecstr: String = row.get(14);
+
+ let date: DateTime<Local> = serde_json::from_str(&dstr).unwrap();
+ let receipt: HashMap<String, i64> = serde_json::from_str(&rstr).unwrap();
+ let extra_content: Option<Value> = serde_json::from_str(&ecstr).unwrap();
+
+ Self {
+ sender: row.get(0),
+ mtype: row.get(1),
+ body: row.get(2),
+ date: date,
+ room: row.get(4),
+ thumb: row.get(5),
+ url: row.get(6),
+ id: row.get(7),
+ formatted_body: row.get(8),
+ format: row.get(9),
+ source: row.get(10),
+ receipt: receipt,
+ redacted: row.get(12),
+ in_reply_to: row.get(13),
+ extra_content: extra_content,
+ }
+ }
+}
diff --git a/fractal-backend/src/model/mod.rs b/fractal-backend/src/model/mod.rs
index d3137fdd..22ba84a4 100644
--- a/fractal-backend/src/model/mod.rs
+++ b/fractal-backend/src/model/mod.rs
@@ -4,7 +4,10 @@ use failure::Error;
use rusqlite::Row;
use rusqlite::NO_PARAMS;
+pub mod message;
pub mod room;
+
+pub use self::message::Message;
pub use self::room::Room;
pub trait Model: Sized {
diff --git a/fractal-backend/tests/models.rs b/fractal-backend/tests/models.rs
index 325e15ee..462eb2a3 100644
--- a/fractal-backend/tests/models.rs
+++ b/fractal-backend/tests/models.rs
@@ -1,6 +1,7 @@
extern crate fractal_backend;
use fractal_backend::init;
+use fractal_backend::model::Message;
use fractal_backend::model::Model;
use fractal_backend::model::Room;
use std::fs::remove_file;
@@ -37,3 +38,25 @@ fn room_model() {
assert_eq!(r.id, format!("ROOM {}", i));
}
}
+
+#[test]
+fn message_model() {
+ let _ = remove_file("/tmp/db.sqlite3");
+ let _ = init("/tmp/db.sqlite3").unwrap();
+
+ let mut msg = Message::default();
+ msg.id = Some("MSGID".to_string());
+ let created = Message::create_table();
+ assert!(created.is_ok());
+ let stored = msg.store();
+ assert!(stored.is_ok());
+
+ let newm = Message::get("MSGID").unwrap();
+ assert_eq!(msg, newm);
+
+ let deleted = msg.delete();
+ assert!(deleted.is_ok());
+
+ let really_deleted = Message::get("MSGID");
+ assert!(really_deleted.is_err());
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]