A personal app view to see Bsky posts of your followers (for when their app view goes down)
1use sqlx::{FromRow, Row, types::chrono};
2
3#[derive(Debug, FromRow)]
4pub struct PostRecord {
5 pub created: chrono::DateTime<chrono::Utc>,
6 pub indexed: chrono::DateTime<chrono::Utc>,
7 pub author: String,
8 pub rkey: String,
9 pub cid: String,
10 // TODO: other fields like reply to etc
11}
12
13#[derive(Debug, FromRow)]
14pub struct RepostRecord {
15 pub created: chrono::DateTime<chrono::Utc>,
16 pub indexed: chrono::DateTime<chrono::Utc>,
17 pub author: String,
18 pub rkey: String,
19 pub subject: String,
20 pub cid: String,
21 // TODO: other fields like reply to etc
22}
23
24pub async fn insert_post(post: PostRecord, pool: &sqlx::SqlitePool) {
25 let result = sqlx::query(
26 "INSERT INTO posts (created, indexed, author, rkey, cid) VALUES ($1, $2, $3, $4, $5)",
27 )
28 .bind(post.created)
29 .bind(post.indexed)
30 .bind(post.author)
31 .bind(post.rkey)
32 .bind(post.cid)
33 .execute(pool)
34 .await;
35
36 if result.is_err() {
37 println!("Error inserting post into the database: {result:?}");
38 }
39}
40
41pub async fn insert_repost(repost: RepostRecord, pool: &sqlx::SqlitePool) {
42 let result = sqlx::query(
43 "INSERT INTO reposts (created, indexed, author, rkey, subject, cid) VALUES ($1, $2, $3, $4, $5, $6)",
44 )
45 .bind(repost.created)
46 .bind(repost.indexed)
47 .bind(repost.author)
48 .bind(repost.rkey)
49 .bind(repost.subject)
50 .bind(repost.cid)
51 .execute(pool)
52 .await;
53
54 if result.is_err() {
55 println!("Error inserting repost into the database: {result:?}");
56 }
57}
58
59pub async fn delete_post(rkey: String, pool: &sqlx::SqlitePool) {
60 let result = sqlx::query("DELETE FROM posts WHERE rkey = $1")
61 .bind(rkey)
62 .execute(pool)
63 .await;
64
65 if result.is_err() {
66 println!("Error deleting post from the database: {result:?}");
67 }
68}
69
70pub async fn delete_repost(rkey: String, pool: &sqlx::SqlitePool) {
71 let result = sqlx::query("DELETE FROM reposts WHERE rkey = $1")
72 .bind(rkey)
73 .execute(pool)
74 .await;
75
76 if result.is_err() {
77 println!("Error deleting repost from the database: {result:?}");
78 }
79}
80
81pub async fn get_follow_by_rkey(rkey: &String, pool: &sqlx::SqlitePool) -> String {
82 let result = sqlx::query("SELECT subject FROM follows where rkey = ? LIMIT 1")
83 .bind(rkey)
84 .fetch_one(pool)
85 .await;
86
87 match result {
88 Ok(row) => {
89 if row.len() == 0 {
90 println!("did not find subject in follows with rkey: {rkey}");
91 return "".to_string();
92 }
93 let subject = row.get::<String, _>(0);
94
95 return subject;
96 }
97 Err(e) => {
98 println!("error getting follow {e}");
99 return "".to_string();
100 }
101 }
102}