1use crate::prelude::*;
2
3#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)]
4#[cfg_attr(feature = "ts_rs", derive(TS))]
5pub struct PlaygroundExample {
6 pub id: Uuid,
7 pub created_at: DateTime<Utc>,
8 pub updated_at: DateTime<Utc>,
9 pub deleted_at: Option<DateTime<Utc>>,
10 pub name: String,
11 pub url: String,
12 pub width: i32,
13 pub data: serde_json::Value,
14}
15
16#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)]
17#[cfg_attr(feature = "ts_rs", derive(TS))]
18pub struct PlaygroundExampleData {
19 pub name: String,
20 pub url: String,
21 pub width: i32,
22 pub data: serde_json::Value,
23}
24
25pub async fn get_all_playground_examples(
26 conn: &mut PgConnection,
27) -> ModelResult<Vec<PlaygroundExample>> {
28 let examples = sqlx::query_as!(
29 PlaygroundExample,
30 "
31SELECT *
32from playground_examples
33WHERE deleted_at IS NULL;
34 "
35 )
36 .fetch_all(&mut *conn)
37 .await?;
38 Ok(examples)
39}
40
41pub async fn insert_playground_example(
42 conn: &mut PgConnection,
43 data: PlaygroundExampleData,
44) -> ModelResult<PlaygroundExample> {
45 let res = sqlx::query!(
46 "
47INSERT INTO playground_examples (name, url, width, data)
48VALUES ($1, $2, $3, $4)
49RETURNING *;
50 ",
51 data.name,
52 data.url,
53 data.width,
54 data.data
55 )
56 .fetch_one(&mut *conn)
57 .await?;
58 Ok(PlaygroundExample {
59 id: res.id,
60 created_at: res.created_at,
61 updated_at: res.updated_at,
62 deleted_at: res.deleted_at,
63 name: res.name,
64 url: res.url,
65 width: res.width,
66 data: res.data,
67 })
68}
69
70pub async fn update_playground_example(
71 conn: &mut PgConnection,
72 data: PlaygroundExample,
73) -> ModelResult<PlaygroundExample> {
74 let res = sqlx::query_as!(
75 PlaygroundExample,
76 "
77UPDATE playground_examples
78SET updated_at = now(),
79 name = $1,
80 url = $2,
81 width = $3,
82 data = $4
83WHERE id = $5
84RETURNING *;
85 ",
86 data.name,
87 data.url,
88 data.width,
89 data.data,
90 data.id
91 )
92 .fetch_one(&mut *conn)
93 .await?;
94
95 Ok(res)
96}
97
98pub async fn delete_playground_example(
99 conn: &mut PgConnection,
100 id: Uuid,
101) -> ModelResult<PlaygroundExample> {
102 let res = sqlx::query!(
103 "
104UPDATE playground_examples
105SET deleted_at = now()
106WHERE id = $1
107AND deleted_at IS NULL
108RETURNING *;
109 ",
110 id
111 )
112 .fetch_one(&mut *conn)
113 .await
114 .unwrap();
115
116 Ok(PlaygroundExample {
117 id: res.id,
118 created_at: res.created_at,
119 updated_at: res.updated_at,
120 deleted_at: res.deleted_at,
121 name: res.name,
122 url: res.url,
123 width: res.width,
124 data: res.data,
125 })
126}
127
128#[cfg(test)]
129mod test {
130
131 use super::*;
132 use crate::{playground_examples::PlaygroundExampleData, test_helper::Conn};
133
134 #[tokio::test]
135 async fn insert_and_fetch_playground_example() {
136 let mut conn = Conn::init().await;
137 let mut tx = conn.begin().await;
138
139 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
140 let previous_length = fetched_data.len();
141
142 let inserted_data = insert_playground_example(
143 tx.as_mut(),
144 PlaygroundExampleData {
145 name: "test".to_string(),
146 url: "https:\\test.com".to_string(),
147 width: 500,
148 data: serde_json::json!({"data":"test"}),
149 },
150 )
151 .await
152 .unwrap();
153
154 assert!(inserted_data.name == *"test");
155 assert!(inserted_data.url == *"https:\\test.com");
156 assert!(inserted_data.width == 500);
157 assert!(inserted_data.data == serde_json::json!({"data":"test"}));
158
159 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
160
161 assert_eq!(fetched_data.len(), previous_length + 1);
162 }
163
164 #[tokio::test]
165 async fn insert_and_delete_playground_example() {
166 let mut conn = Conn::init().await;
167 let mut tx = conn.begin().await;
168
169 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
170 let previous_length = fetched_data.len();
171
172 let inserted_data = insert_playground_example(
173 tx.as_mut(),
174 PlaygroundExampleData {
175 name: "test".to_string(),
176 url: "https:\\test.com".to_string(),
177 width: 500,
178 data: serde_json::json!({"data":"test"}),
179 },
180 )
181 .await
182 .unwrap();
183
184 assert!(inserted_data.name == *"test");
185 assert!(inserted_data.url == *"https:\\test.com");
186 assert!(inserted_data.width == 500);
187 assert!(inserted_data.data == serde_json::json!({"data":"test"}));
188
189 let res = delete_playground_example(tx.as_mut(), inserted_data.id)
190 .await
191 .unwrap();
192
193 assert!(res.deleted_at.is_some());
194
195 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
196
197 assert_eq!(fetched_data.len(), previous_length);
198 }
199
200 #[tokio::test]
201 async fn insert_and_update_playground_example() {
202 let mut conn = Conn::init().await;
203 let mut tx = conn.begin().await;
204
205 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
206 let previous_length = fetched_data.len();
207
208 let inserted_data = insert_playground_example(
209 tx.as_mut(),
210 PlaygroundExampleData {
211 name: "test".to_string(),
212 url: "https:\\test.com".to_string(),
213 width: 500,
214 data: serde_json::json!({"data":"test"}),
215 },
216 )
217 .await
218 .unwrap();
219
220 assert!(inserted_data.name == *"test");
221 assert!(inserted_data.url == *"https:\\test.com");
222 assert!(inserted_data.width == 500);
223 assert!(inserted_data.data == serde_json::json!({"data":"test"}));
224
225 let updated_data = PlaygroundExample {
226 name: "updated name".to_string(),
227 url: "https:\\updated-url.com".to_string(),
228 width: 600,
229 data: serde_json::json!({"data": "updated data"}),
230 ..inserted_data
231 };
232
233 let res = update_playground_example(tx.as_mut(), updated_data)
234 .await
235 .unwrap();
236
237 assert!(res.name == *"updated name");
238 assert!(res.url == *"https:\\updated-url.com");
239 assert!(res.width == 600);
240 assert!(res.data == serde_json::json!({"data":"updated data"}));
241
242 let fetched_data = get_all_playground_examples(tx.as_mut()).await.unwrap();
243
244 assert_eq!(fetched_data.len(), previous_length + 1);
245 }
246}