arminius_lib_db_devices/
lib.rs1mod tests;
8
9use arminius_lib_db::{Database, DatabaseError};
10use ruma::{DeviceId, OwnedDeviceId, UserId};
11
12#[derive(Debug)]
14pub struct Device {
15 pub device_id: OwnedDeviceId,
17}
18
19#[rust_analyzer::prefer_underscore_import]
22pub trait DeviceQueries: Database {
23 #[tracing::instrument(skip(self))]
25 async fn fetch_devices_for_user(
26 &mut self,
27 user_id: &UserId,
28 ) -> Result<Vec<Device>, DatabaseError> {
29 Ok(sqlx::query_as!(
30 Device,
31 "SELECT device_id FROM devices WHERE user_nid = (SELECT nid FROM users WHERE user_id = $1)",
32 user_id.as_str()
33 )
34 .fetch_all(self.connection().await?)
35 .await?)
36 }
37
38 #[tracing::instrument(skip(self))]
40 async fn fetch_device_for_user(
41 &mut self,
42 user_id: &UserId,
43 device_id: &DeviceId,
44 ) -> Result<Option<Device>, DatabaseError> {
45 Ok(sqlx::query_as!(
46 Device,
47 "SELECT device_id FROM devices WHERE user_nid = (SELECT nid FROM users WHERE user_id = $1) AND device_id = $2",
48 user_id.as_str(),
49 device_id.as_str(),
50 )
51 .fetch_optional(self.connection().await?)
52 .await?)
53 }
54
55 #[tracing::instrument(skip(self))]
59 async fn insert_device_for_user(
60 &mut self,
61 user_id: &UserId,
62 device_id: &DeviceId,
63 ) -> Result<(), DatabaseError> {
64 sqlx::query!(
65 "INSERT INTO devices (user_nid, device_id, idp_id)
66 VALUES ((SELECT nid FROM users WHERE user_id = $1), $2, $2)",
67 user_id.to_string(),
68 device_id.to_string()
69 )
70 .execute(self.connection().await?)
71 .await?;
72
73 Ok(())
74 }
75
76 #[tracing::instrument(skip(self))]
80 async fn import_device(
81 &mut self,
82 user_id: &UserId,
83 device_id: &DeviceId,
84 ) -> Result<bool, DatabaseError> {
85 let result = sqlx::query!(
86 r#"
87 INSERT INTO devices (user_nid, device_id, idp_id)
88 VALUES ((
89 SELECT
90 nid
91 FROM
92 users
93 WHERE
94 user_id = $1), $2, NULL)
95 ON CONFLICT (user_nid,
96 device_id)
97 DO NOTHING
98 "#,
99 user_id.as_str(),
100 device_id.as_str(),
101 )
102 .execute(self.connection().await?)
103 .await?;
104 Ok(result.rows_affected() > 0)
105 }
106
107 #[cfg(feature = "test_utils")]
110 #[tracing::instrument(skip(self))]
111 async fn insert_test_user_with_device(
112 &mut self,
113 user_id: &UserId,
114 device_id: &DeviceId,
115 ) -> Result<(), DatabaseError> {
116 sqlx::query!(
120 "WITH new_user AS
121 (INSERT INTO users(user_id, idp_id) VALUES ($1, $1) ON CONFLICT (user_id) DO UPDATE SET user_id = EXCLUDED.user_id RETURNING nid)
122 INSERT INTO devices(user_nid, device_id, idp_id) VALUES ((SELECT nid FROM new_user), $2, $2) ON CONFLICT (user_nid, device_id) DO NOTHING",
123 user_id.as_str(),
124 device_id.as_str(),
125 )
126 .execute(self.connection().await?)
127 .await?;
128 Ok(())
129 }
130}
131
132impl<T> DeviceQueries for T where T: Database {}