hypercall_db_diesel/
push.rs1use anyhow::Result;
6use async_trait::async_trait;
7use diesel::prelude::*;
8use diesel_async::RunQueryDsl;
9
10use crate::diesel_db::DieselDb;
11use crate::models::{NewPushSubscription, PushSubscription};
12use crate::schema::push_subscriptions;
13use hypercall_db::{
14 PushSubscriptionReader, PushSubscriptionRecord, PushSubscriptionWriter,
15 UpsertPushSubscriptionInput,
16};
17
18impl From<PushSubscription> for PushSubscriptionRecord {
21 fn from(row: PushSubscription) -> Self {
22 Self {
23 id: row.id,
24 wallet_address: row.wallet_address,
25 endpoint: row.endpoint,
26 auth_key: row.auth_key,
27 p256dh_key: row.p256dh_key,
28 preferences: row.preferences,
29 created_at: row.created_at,
30 }
31 }
32}
33
34#[async_trait]
39impl PushSubscriptionReader for DieselDb {
40 async fn get_push_subscriptions(&self, wallet: &str) -> Result<Vec<PushSubscriptionRecord>> {
41 let mut conn = self.get_conn().await?;
42 let wallet_lower = wallet.to_lowercase();
43
44 let rows = push_subscriptions::table
45 .filter(push_subscriptions::wallet_address.eq(&wallet_lower))
46 .load::<PushSubscription>(&mut conn)
47 .await?;
48
49 Ok(rows.into_iter().map(Into::into).collect())
50 }
51
52 async fn count_push_subscriptions(&self, wallet: &str) -> Result<i64> {
53 let mut conn = self.get_conn().await?;
54 let wallet_lower = wallet.to_lowercase();
55
56 let count = push_subscriptions::table
57 .filter(push_subscriptions::wallet_address.eq(&wallet_lower))
58 .count()
59 .get_result::<i64>(&mut conn)
60 .await?;
61
62 Ok(count)
63 }
64
65 async fn push_subscription_exists(&self, wallet: &str, endpoint: &str) -> Result<bool> {
66 let mut conn = self.get_conn().await?;
67 let wallet_lower = wallet.to_lowercase();
68
69 let count = push_subscriptions::table
70 .filter(push_subscriptions::wallet_address.eq(&wallet_lower))
71 .filter(push_subscriptions::endpoint.eq(endpoint))
72 .count()
73 .get_result::<i64>(&mut conn)
74 .await?;
75
76 Ok(count > 0)
77 }
78}
79
80#[async_trait]
85impl PushSubscriptionWriter for DieselDb {
86 async fn upsert_push_subscription(
87 &self,
88 input: UpsertPushSubscriptionInput,
89 ) -> Result<PushSubscriptionRecord> {
90 let mut conn = self.get_conn().await?;
91
92 let row = diesel::insert_into(push_subscriptions::table)
93 .values(NewPushSubscription {
94 wallet_address: input.wallet_address,
95 endpoint: input.endpoint,
96 auth_key: input.auth_key.clone(),
97 p256dh_key: input.p256dh_key.clone(),
98 preferences: input.preferences.clone(),
99 })
100 .on_conflict((
101 push_subscriptions::wallet_address,
102 push_subscriptions::endpoint,
103 ))
104 .do_update()
105 .set((
106 push_subscriptions::auth_key.eq(&input.auth_key),
107 push_subscriptions::p256dh_key.eq(&input.p256dh_key),
108 push_subscriptions::preferences.eq(&input.preferences),
109 ))
110 .get_result::<PushSubscription>(&mut conn)
111 .await?;
112
113 Ok(row.into())
114 }
115
116 async fn update_push_preferences(
117 &self,
118 wallet: &str,
119 endpoint: &str,
120 preferences: serde_json::Value,
121 ) -> Result<bool> {
122 let mut conn = self.get_conn().await?;
123 let wallet_lower = wallet.to_lowercase();
124
125 let updated = diesel::update(
126 push_subscriptions::table
127 .filter(push_subscriptions::wallet_address.eq(&wallet_lower))
128 .filter(push_subscriptions::endpoint.eq(endpoint)),
129 )
130 .set(push_subscriptions::preferences.eq(&preferences))
131 .execute(&mut conn)
132 .await?;
133
134 Ok(updated > 0)
135 }
136
137 async fn delete_push_subscription(&self, wallet: &str, endpoint: &str) -> Result<bool> {
138 let mut conn = self.get_conn().await?;
139 let wallet_lower = wallet.to_lowercase();
140
141 let deleted = diesel::delete(
142 push_subscriptions::table
143 .filter(push_subscriptions::wallet_address.eq(&wallet_lower))
144 .filter(push_subscriptions::endpoint.eq(endpoint)),
145 )
146 .execute(&mut conn)
147 .await?;
148
149 Ok(deleted > 0)
150 }
151
152 async fn delete_push_subscription_by_id(&self, id: i64) -> Result<bool> {
153 let mut conn = self.get_conn().await?;
154
155 let deleted = diesel::delete(push_subscriptions::table.find(id))
156 .execute(&mut conn)
157 .await?;
158
159 Ok(deleted > 0)
160 }
161}