summaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/database')
-rw-r--r--src/database/friends.rs97
-rw-r--r--src/database/likes.rs8
-rw-r--r--src/database/mod.rs2
-rw-r--r--src/database/users.rs2
4 files changed, 103 insertions, 6 deletions
diff --git a/src/database/friends.rs b/src/database/friends.rs
new file mode 100644
index 0000000..0b78488
--- /dev/null
+++ b/src/database/friends.rs
@@ -0,0 +1,97 @@
+use tracing::instrument;
+
+use crate::{
+ database::{self, users::user_from_row},
+ types::user::{User, FOLLOWED, FOLLOWING, NO_RELATION},
+};
+
+pub fn init() -> Result<(), rusqlite::Error> {
+ let sql = "
+ CREATE TABLE IF NOT EXISTS friends (
+ follower_id INTEGER NOT NULL,
+ followee_id INTEGER NOT NULL,
+ FOREIGN KEY(follower_id) REFERENCES users(user_id),
+ FOREIGN KEY(followee_id) REFERENCES users(user_id),
+ PRIMARY KEY (follower_id, followee_id)
+ );
+ ";
+ let conn = database::connect()?;
+ conn.execute(sql, ())?;
+ Ok(())
+}
+
+#[instrument()]
+pub fn get_friend_status(user_id_1: u64, user_id_2: u64) -> Result<u8, rusqlite::Error> {
+ tracing::trace!("Retrieving friend status");
+ let conn = database::connect()?;
+ let mut stmt = conn.prepare("SELECT * FROM friends WHERE (follower_id = ? AND followee_id = ?) OR (follower_id = ? AND followee_id = ?);")?;
+ let mut status = NO_RELATION;
+ let rows: Vec<u64> = stmt
+ .query_map([user_id_1, user_id_2, user_id_2, user_id_1], |row| {
+ let id: u64 = row.get(0)?;
+ Ok(id)
+ })?
+ .into_iter()
+ .flatten()
+ .collect();
+
+ for follower in rows {
+ if follower == user_id_1 {
+ status |= FOLLOWING;
+ }
+
+ if follower == user_id_2 {
+ status |= FOLLOWED;
+ }
+ }
+
+ Ok(status)
+}
+
+#[instrument()]
+pub fn get_friends(user_id: u64) -> Result<Vec<User>, rusqlite::Error> {
+ tracing::trace!("Retrieving friends");
+ let conn = database::connect()?;
+ let mut stmt = conn.prepare(
+ "
+ SELECT *
+ FROM users u
+ WHERE EXISTS (
+ SELECT NULL
+ FROM friends f
+ WHERE u.user_id = f.follower_id
+ AND f.followee_id = ?
+ )
+ AND EXISTS (
+ SELECT NULL
+ FROM friends f
+ WHERE u.user_id = f.followee_id
+ AND f.follower_id = ?
+ )
+ ",
+ )?;
+ let row = stmt.query_map([user_id, user_id], |row| {
+ let row = user_from_row(row, true)?;
+ Ok(row)
+ })?;
+ Ok(row.into_iter().flatten().collect())
+}
+
+#[instrument()]
+pub fn set_following(user_id_1: u64, user_id_2: u64) -> Result<bool, rusqlite::Error> {
+ tracing::trace!("Setting following");
+ let conn = database::connect()?;
+ let mut stmt =
+ conn.prepare("INSERT OR REPLACE INTO friends (follower_id, followee_id) VALUES (?,?)")?;
+ let changes = stmt.execute([user_id_1, user_id_2])?;
+ Ok(changes == 1)
+}
+
+#[instrument()]
+pub fn remove_following(user_id_1: u64, user_id_2: u64) -> Result<bool, rusqlite::Error> {
+ tracing::trace!("Removing following");
+ let conn = database::connect()?;
+ let mut stmt = conn.prepare("DELETE FROM friends WHERE follower_id = ? AND followee_id = ?")?;
+ let changes = stmt.execute([user_id_1, user_id_2])?;
+ Ok(changes == 1)
+}
diff --git a/src/database/likes.rs b/src/database/likes.rs
index 6f6939e..f6a130b 100644
--- a/src/database/likes.rs
+++ b/src/database/likes.rs
@@ -37,9 +37,7 @@ pub fn get_liked(user_id: u64, post_id: u64) -> Result<bool, rusqlite::Error> {
tracing::trace!("Retrieving if liked");
let conn = database::connect()?;
let mut stmt = conn.prepare("SELECT * FROM likes WHERE user_id = ? AND post_id = ?")?;
- let liked = stmt.query_row([user_id, post_id], |_| {
- Ok(())
- }).optional()?;
+ let liked = stmt.query_row([user_id, post_id], |_| Ok(())).optional()?;
Ok(liked.is_some())
}
@@ -49,7 +47,7 @@ pub fn add_liked(user_id: u64, post_id: u64) -> Result<bool, rusqlite::Error> {
let conn = database::connect()?;
let mut stmt = conn.prepare("INSERT OR REPLACE INTO likes (user_id, post_id) VALUES (?,?)")?;
let changes = stmt.execute([user_id, post_id])?;
- Ok(changes == 1)
+ Ok(changes == 1)
}
#[instrument()]
@@ -69,7 +67,7 @@ pub fn get_all_likes() -> Result<Vec<Like>, rusqlite::Error> {
let row = stmt.query_map([], |row| {
let like = Like {
user_id: row.get(0)?,
- post_id: row.get(1)?
+ post_id: row.get(1)?,
};
Ok(like)
})?;
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 6d4853a..d22a350 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -1,6 +1,7 @@
use tracing::instrument;
pub mod comments;
+pub mod friends;
pub mod likes;
pub mod posts;
pub mod sessions;
@@ -16,6 +17,7 @@ pub fn init() -> Result<(), rusqlite::Error> {
sessions::init()?;
likes::init()?;
comments::init()?;
+ friends::init()?;
Ok(())
}
diff --git a/src/database/users.rs b/src/database/users.rs
index 15565f1..6062ea8 100644
--- a/src/database/users.rs
+++ b/src/database/users.rs
@@ -31,7 +31,7 @@ pub fn init() -> Result<(), rusqlite::Error> {
Ok(())
}
-fn user_from_row(row: &Row, hide_password: bool) -> Result<User, rusqlite::Error> {
+pub fn user_from_row(row: &Row, hide_password: bool) -> Result<User, rusqlite::Error> {
let user_id = row.get(0)?;
let firstname = row.get(1)?;
let lastname = row.get(2)?;