• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

szabgab / meet-os.rs / 10878757730

16 Sep 2024 06:37AM UTC coverage: 95.034% (-0.1%) from 95.133%
10878757730

push

github

szabgab
add status to the events #50

16 of 17 new or added lines in 1 file covered. (94.12%)

16 existing lines in 1 file now uncovered.

1244 of 1309 relevant lines covered (95.03%)

79.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.91
/src/db.rs
1
use chrono::{DateTime, Utc};
2
use serde::{Deserialize, Serialize};
3

4
use rocket::fairing::AdHoc;
5
use surrealdb::engine::remote::ws::Client;
6
use surrealdb::engine::remote::ws::Ws;
7
use surrealdb::opt::Resource;
8
use surrealdb::Surreal;
9

10
use crate::EventStatus;
11
use crate::{Audit, Counter, Event, Group, Membership, MyConfig, User, RSVP};
12

13
/// # Panics
14
///
15
/// Panics when it fails to create the database folder or set up the database.
16
#[must_use]
17
pub fn fairing() -> AdHoc {
99✔
18
    // TODO handle errors here properly by using AdHoc::try_on_ignite instead of AdHoc::on_ignite.
19
    AdHoc::on_ignite("Managed Database Connection", |rocket| async {
198✔
20
        let config = rocket.state::<MyConfig>().unwrap();
99✔
21

22
        let dbh = get_database(&config.database_name, &config.database_namespace).await;
1,682✔
23

24
        rocket.manage(dbh)
99✔
25
    })
26
}
27

28
/// # Panics
29
///
30
/// Panics when it fails to create the database folder or set up the database.
31
pub async fn get_database(db_name: &str, db_namespace: &str) -> Surreal<Client> {
204✔
32
    let address = "127.0.0.1:8000";
102✔
33
    let dbh = Surreal::new::<Ws>(address).await.unwrap();
815✔
34
    dbh.use_ns(db_namespace).use_db(db_name).await.unwrap();
306✔
35

36
    upgrade(&dbh).await.unwrap();
1,122✔
37

38
    dbh
102✔
39
}
40

41
/// # Panics
42
///
43
/// Panics when there is an error
44
pub async fn upgrade(dbh: &Surreal<Client>) -> surrealdb::Result<()> {
204✔
45
    let version = get_schema_version(dbh).await.unwrap();
408✔
46
    rocket::info!("Upgrade from {version}");
204✔
47

48
    if version == 0 {
102✔
49
        upgrade_to_1(dbh).await?;
714✔
50
        upgrade_to_2(dbh).await?;
306✔
51
    }
52
    if version == 1 {
102✔
NEW
53
        upgrade_to_2(dbh).await?;
×
54
    }
55

56
    Ok(())
102✔
57
}
58

59
/// # Panics
60
///
61
/// Panics when there is an error
62
pub async fn upgrade_to_1(dbh: &Surreal<Client>) -> surrealdb::Result<()> {
204✔
63
    rocket::info!("upgrade_to_1");
204✔
64

65
    dbh.query("DEFINE INDEX user_email ON TABLE user COLUMNS email UNIQUE")
102✔
66
        .await
102✔
67
        .unwrap()
68
        .check()
69
        .unwrap();
70
    dbh.query("DEFINE INDEX user_uid ON TABLE user COLUMNS uid UNIQUE")
102✔
71
        .await
102✔
72
        .unwrap()
73
        .check()
74
        .unwrap();
75

76
    // We can't set this to unique as we are converting them to the empty string when the code is used
77
    // dbh.query("DEFINE INDEX user_code ON TABLE user COLUMNS code UNIQUE")
78
    //     .await
79
    //     .unwrap()
80
    //     .check()
81
    //     .unwrap();
82

83
    dbh.query("DEFINE INDEX group_gid ON TABLE group COLUMNS gid UNIQUE")
102✔
84
        .await
102✔
85
        .unwrap()
86
        .check()
87
        .unwrap();
88

89
    dbh.query("DEFINE INDEX member_ship ON TABLE membership COLUMNS uid, gid UNIQUE")
102✔
90
        .await
102✔
91
        .unwrap()
92
        .check()
93
        .unwrap();
94

95
    dbh.query("DEFINE INDEX rsvp_index ON TABLE rsvp COLUMNS uid, eid UNIQUE")
102✔
96
        .await
102✔
97
        .unwrap()
98
        .check()
99
        .unwrap();
100

101
    create_schema_version(dbh).await?;
204✔
102
    Ok(())
102✔
103
}
104

105
/// # Panics
106
///
107
/// Panics when there is an error
108
pub async fn upgrade_to_2(dbh: &Surreal<Client>) -> surrealdb::Result<()> {
204✔
109
    rocket::info!("upgrade_to_2");
204✔
110

111
    dbh.query("UPDATE event SET status=$status")
102✔
112
        .bind(("status", EventStatus::Published))
102✔
113
        .await?;
102✔
114

115
    update_schema_version(dbh, 2).await?;
204✔
116
    Ok(())
102✔
117
}
118

119
#[derive(Debug, Serialize, Deserialize)]
120
struct Schema {
121
    version: u64,
122
}
123

124
async fn get_schema_version(dbh: &Surreal<Client>) -> surrealdb::Result<u64> {
204✔
125
    let mut response = dbh.query("SELECT * from schema").await?;
306✔
126
    let versions: Vec<Schema> = response.take(0)?;
204✔
UNCOV
127
    if let Some(schema) = versions.first() {
×
UNCOV
128
        return Ok(schema.version);
×
129
    }
130

131
    Ok(0)
102✔
132
}
133

134
async fn create_schema_version(dbh: &Surreal<Client>) -> surrealdb::Result<()> {
204✔
135
    let _created: Vec<Schema> = dbh.create("schema").content(Schema { version: 1 }).await?;
306✔
136

137
    Ok(())
102✔
138
}
139

140
async fn update_schema_version(dbh: &Surreal<Client>, version: u64) -> surrealdb::Result<()> {
204✔
141
    dbh.query("UPDATE schema SET version=$version")
102✔
142
        .bind(("version", version))
102✔
143
        .await?;
102✔
144

145
    Ok(())
102✔
146
}
147

148
pub async fn add_user(dbh: &Surreal<Client>, user: &User) -> surrealdb::Result<()> {
352✔
149
    rocket::info!("add user email: '{}' code: '{}'", user.email, user.code);
352✔
150

151
    dbh.create(Resource::from("user")).content(user).await?;
355✔
152

153
    Ok(())
173✔
154
}
155

156
pub async fn add_event(dbh: &Surreal<Client>, event: &Event) -> surrealdb::Result<()> {
82✔
157
    rocket::info!("add event: '{}' code: '{}'", event.eid, event.title);
82✔
158

159
    dbh.create(Resource::from("event")).content(event).await?;
82✔
160

161
    Ok(())
41✔
162
}
163

164
pub async fn update_event(dbh: &Surreal<Client>, event: &Event) -> surrealdb::Result<()> {
4✔
165
    rocket::info!(
2✔
166
        "update_event: eid: '{}' new title: '{}'",
2✔
167
        event.eid,
168
        event.title
169
    );
170

171
    let mut response = dbh
4✔
172
        .query(
173
            "
174
            UPDATE event
175
                SET
176
                    title=$title,
177
                    date=$date,
178
                    location=$location,
179
                    description=$description
180
                WHERE eid=$eid;",
181
        )
182
        .bind(("title", event.title.clone()))
2✔
183
        .bind(("location", event.location.clone()))
2✔
184
        .bind(("date", event.date))
2✔
185
        .bind(("description", event.description.clone()))
2✔
186
        .bind(("eid", event.eid))
2✔
187
        .await?;
2✔
188

189
    rocket::info!("response {:?}", response);
4✔
190
    let entry: Option<Event> = response.take(0)?;
4✔
191
    if let Some(entry) = entry.as_ref() {
2✔
192
        rocket::info!("event updated '{}', '{}'", entry.title, entry.date);
2✔
193
    }
194

195
    Ok(())
2✔
196
}
197

198
pub async fn add_group(dbh: &Surreal<Client>, group: &Group) -> surrealdb::Result<()> {
114✔
199
    rocket::info!("add group: '{}'", group.name);
114✔
200

201
    dbh.create(Resource::from("group")).content(group).await?;
115✔
202

203
    Ok(())
56✔
204
}
205

206
pub async fn get_user_by_code(
2✔
207
    dbh: &Surreal<Client>,
208
    process: &str,
209
    code: &str,
210
) -> surrealdb::Result<Option<User>> {
211
    rocket::info!("verification code: '{code}' process = '{process}'");
4✔
212

213
    let mut response = dbh
4✔
214
        .query("SELECT * FROM user WHERE code=$code AND process=$process;")
215
        .bind(("code", code))
2✔
216
        .bind(("process", process))
2✔
217
        .await?;
2✔
218

219
    let entry: Option<User> = response.take(0)?;
4✔
220

221
    if let Some(entry) = entry.as_ref() {
1✔
222
        rocket::info!("Found user {}, {}", entry.name, entry.email);
1✔
223
    }
224

225
    Ok(entry)
2✔
226
}
227

228
pub async fn set_user_verified(
166✔
229
    dbh: &Surreal<Client>,
230
    uid: usize,
231
) -> surrealdb::Result<Option<User>> {
232
    rocket::info!("set_user_verified: '{uid}'");
332✔
233
    let utc: DateTime<Utc> = Utc::now();
166✔
234
    let mut response = dbh
166✔
235
        .query(
236
            "
237
            UPDATE user
238
                SET
239
                    verified=$verified,
240
                    code='',
241
                    verification_date=$date
242
                WHERE uid=$uid;",
243
        )
UNCOV
244
        .bind(("verified", true))
×
UNCOV
245
        .bind(("date", utc))
×
UNCOV
246
        .bind(("uid", uid))
×
247
        .await?;
166✔
248

249
    let entry: Option<User> = response.take(0)?;
332✔
250

251
    if let Some(entry) = entry.as_ref() {
166✔
UNCOV
252
        rocket::info!(
×
253
            "verification ok '{}', '{}', '{}'",
166✔
254
            entry.name,
255
            entry.email,
256
            entry.process
257
        );
258
    }
259

260
    Ok(entry)
166✔
261
}
262

263
pub async fn update_group(
1✔
264
    dbh: &Surreal<Client>,
265
    gid: usize,
266
    name: &str,
267
    location: &str,
268
    description: &str,
269
) -> surrealdb::Result<Option<Group>> {
270
    rocket::info!("update group: '{gid}'");
2✔
271

272
    let mut response = dbh
2✔
273
        .query(
274
            "
275
            UPDATE group
276
            SET
277
                name=$name,
278
                location=$location,
279
                description=$description
280
            WHERE gid=$gid;",
281
        )
282
        .bind(("name", name))
1✔
283
        .bind(("location", location))
1✔
284
        .bind(("description", description))
1✔
285
        .bind(("gid", gid))
1✔
286
        .await?;
1✔
287

288
    let entry: Option<Group> = response.take(0)?;
2✔
289
    Ok(entry)
1✔
290
}
291

292
pub async fn remove_code(dbh: &Surreal<Client>, uid: usize) -> surrealdb::Result<Option<User>> {
334✔
293
    rocket::info!("remove code '{uid}'");
334✔
294

295
    let mut response = dbh
334✔
296
        .query(
297
            "
298
            UPDATE user
299
            SET
300
                code=''
301
            WHERE uid=$uid;",
302
        )
303
        .bind(("uid", uid))
167✔
304
        .await?;
167✔
305

306
    let entry: Option<User> = response.take(0)?;
334✔
307
    Ok(entry)
167✔
308
}
309

310
pub async fn save_password(
1✔
311
    dbh: &Surreal<Client>,
312
    uid: usize,
313
    password: &str,
314
) -> surrealdb::Result<Option<User>> {
315
    rocket::info!("save password for '{uid}'");
2✔
316

317
    let mut response = dbh
2✔
318
        .query(
319
            "
320
            UPDATE user
321
            SET
322
                password=$password
323
            WHERE uid=$uid;",
324
        )
325
        .bind(("password", password))
1✔
326
        .bind(("uid", uid))
1✔
327
        .await?;
1✔
328

329
    let entry: Option<User> = response.take(0)?;
2✔
330
    Ok(entry)
1✔
331
}
332

333
pub async fn update_user(
1✔
334
    dbh: &Surreal<Client>,
335
    uid: usize,
336
    name: &str,
337
    github: &str,
338
    gitlab: &str,
339
    linkedin: &str,
340
    about: &str,
341
) -> surrealdb::Result<Option<User>> {
342
    rocket::info!("update user: '{uid}'");
2✔
343

344
    let mut response = dbh
2✔
345
        .query(
346
            "
347
            UPDATE user
348
            SET
349
                name=$name,
350
                about=$about,
351
                gitlab=$gitlab,
352
                linkedin=$linkedin,
353
                github=$github
354
            WHERE uid=$uid;",
355
        )
356
        .bind(("name", name))
1✔
357
        .bind(("github", github))
1✔
358
        .bind(("gitlab", gitlab))
1✔
359
        .bind(("linkedin", linkedin))
1✔
360
        .bind(("uid", uid))
1✔
361
        .bind(("about", about))
1✔
362
        .await?;
1✔
363

364
    let entry: Option<User> = response.take(0)?;
2✔
365
    Ok(entry)
1✔
366
}
367

368
pub async fn get_user_by_id(dbh: &Surreal<Client>, uid: usize) -> surrealdb::Result<Option<User>> {
608✔
369
    rocket::info!("get_user_by_id: '{uid}'");
608✔
370

371
    let mut response = dbh
608✔
372
        .query("SELECT * FROM user WHERE uid=$uid;")
373
        .bind(("uid", uid))
304✔
374
        .await?;
304✔
375

376
    let entry: Option<User> = response.take(0)?;
608✔
377

378
    if let Some(entry) = entry.as_ref() {
299✔
379
        rocket::info!("Found user {}, {}", entry.name, entry.email);
299✔
380
    }
381

382
    Ok(entry)
304✔
383
}
384

385
pub async fn get_user_by_email(
937✔
386
    dbh: &Surreal<Client>,
387
    email: &str,
388
) -> surrealdb::Result<Option<User>> {
389
    rocket::info!("get_user_by_email: '{email}'");
1,874✔
390
    let mut response = dbh
1,874✔
391
        .query("SELECT * FROM user WHERE email=$email;")
392
        .bind(("email", email))
937✔
393
        .await?;
937✔
394

395
    let entry: Option<User> = response.take(0)?;
1,874✔
396

397
    if let Some(entry) = entry.as_ref() {
934✔
398
        rocket::info!("************* {}, {}", entry.name, entry.email);
934✔
399
    }
400

401
    Ok(entry)
937✔
402
}
403

404
pub async fn add_login_code_to_user(
2✔
405
    dbh: &Surreal<Client>,
406
    email: &str,
407
    process: &str,
408
    code: &str,
409
) -> surrealdb::Result<Option<User>> {
410
    rocket::info!("add_login_code_to_user: '{email}', '{process}', '{code}'");
4✔
411
    let mut response = dbh
4✔
412
        .query("UPDATE user SET code=$code, process=$process WHERE email=$email;")
413
        .bind(("email", email))
2✔
414
        .bind(("process", process))
2✔
415
        .bind(("code", code))
2✔
416
        .await?;
2✔
417

418
    let entry: Option<User> = response.take(0)?;
4✔
419

420
    if let Some(entry) = entry.as_ref() {
2✔
421
        rocket::info!("entry: '{}' '{}'", entry.email, entry.process);
2✔
422
    }
423

424
    Ok(entry)
2✔
425
}
426

427
#[must_use]
428
pub async fn get_events_by_group_id(dbh: &Surreal<Client>, gid: usize) -> Vec<Event> {
14✔
429
    match get_events(dbh).await {
14✔
430
        Ok(events) => events
7✔
431
            .into_iter()
432
            .filter(|event| event.group_id == gid)
17✔
433
            .collect(),
UNCOV
434
        Err(_) => vec![],
×
435
    }
436
}
437

438
pub async fn get_users(dbh: &Surreal<Client>) -> surrealdb::Result<Vec<User>> {
14✔
439
    rocket::info!("get_users");
14✔
440
    let mut response = dbh.query("SELECT * FROM user;").await?;
21✔
441
    let entries: Vec<User> = response.take(0)?;
14✔
442
    for ent in &entries {
43✔
443
        rocket::info!("user name {}", ent.name);
18✔
444
    }
445
    Ok(entries)
7✔
446
}
447

448
pub async fn get_groups(dbh: &Surreal<Client>) -> surrealdb::Result<Vec<Group>> {
22✔
449
    rocket::info!("get_groups");
22✔
450
    let mut response = dbh.query("SELECT * FROM group;").await?;
33✔
451
    let entries: Vec<Group> = response.take(0)?;
22✔
452
    for ent in &entries {
31✔
453
        rocket::info!("group name {}", ent.name);
10✔
454
    }
455
    Ok(entries)
11✔
456
}
457

458
/// # Panics
459
///
460
/// Panics when there is an error
461
pub async fn get_groups_by_membership_id(
11✔
462
    dbh: &Surreal<Client>,
463
    uid: usize,
464
) -> surrealdb::Result<Vec<(Group, Membership)>> {
465
    rocket::info!("get_groups_by_membership_id: '{uid}'");
22✔
466

467
    // let mut response = dbh
468
    // .query("SELECT * FROM membership WHERE uid=$uid;")
469
    // .bind(("uid", uid))
470
    // .await?;
471

472
    // let entries: Vec<Membership> = response.take(0)?;
473
    // rocket::info!("gids: {entries:?}");
474

475
    // let mut response = dbh
476
    // .query("SELECT gid FROM membership WHERE uid=$uid;")
477
    // .bind(("uid", uid))
478
    // .await?;
479

480
    // let entries: Vec<String> = response.take(0)?;
481
    // rocket::info!("gids: {entries:?}");
482

483
    // let mut response = dbh
484
    //     .query("SELECT * FROM group WHERE gid IN (SELECT gid FROM membership WHERE uid=$uid);")
485
    //     .bind(("uid", uid))
486
    //     .await?;
487

488
    // let mut response = dbh
489
    //     .query("SELECT * FROM group, membership WHERE group.gid=membership.gid AND membership.uid=$uid;")
490
    //     .bind(("uid", uid))
491
    //     .await?;
492

493
    // TODO: make the code above with subexpression work
494
    let mut response = dbh
22✔
495
        .query("SELECT * FROM membership WHERE uid=$uid;")
496
        .bind(("uid", uid))
11✔
497
        .await?;
11✔
498

499
    let memberships: Vec<Membership> = response.take(0)?;
22✔
500
    rocket::info!("members: {memberships:?}");
11✔
501

502
    let mut groups = vec![];
11✔
503
    for member in memberships {
11✔
UNCOV
504
        rocket::info!("gid: {}", member.gid);
×
UNCOV
505
        let mut response2 = dbh
×
506
            .query("SELECT * FROM group WHERE gid=$gid;")
UNCOV
507
            .bind(("gid", member.gid))
×
UNCOV
508
            .await?;
×
509

UNCOV
510
        let entries: Vec<Group> = response2.take(0)?;
×
UNCOV
511
        rocket::info!("entries: {entries:?}");
×
UNCOV
512
        let group = entries.first().unwrap().clone();
×
513
        //groups.push((group, member.join_date));
UNCOV
514
        groups.push((group, member));
×
515
    }
516

517
    Ok(groups)
11✔
518
}
519

520
/// # Panics
521
///
522
/// Panics when there is an error
523
pub async fn get_members_of_group(
8✔
524
    dbh: &Surreal<Client>,
525
    gid: usize,
526
) -> surrealdb::Result<Vec<(User, Membership)>> {
527
    rocket::info!("get_members_of_group: '{gid}'");
16✔
528

529
    let mut response = dbh
16✔
530
        .query("SELECT * FROM membership WHERE gid=$gid;")
531
        .bind(("gid", gid))
8✔
532
        .await?;
8✔
533

534
    let memberships: Vec<Membership> = response.take(0)?;
16✔
535
    rocket::info!("members: {memberships:?}");
8✔
536

537
    let mut users = vec![];
8✔
538
    for member in memberships {
16✔
539
        rocket::info!("uid: {}", member.uid);
4✔
540
        let mut response2 = dbh
8✔
541
            .query("SELECT * FROM user WHERE uid=$uid;")
542
            .bind(("uid", member.uid))
4✔
543
            .await?;
4✔
544

545
        let entries: Vec<User> = response2.take(0)?;
8✔
546
        rocket::info!("entries: {entries:?}");
4✔
547
        let user = entries.first().unwrap().clone();
4✔
548
        users.push((user, member));
4✔
549
    }
550

551
    Ok(users)
8✔
552
}
553

554
pub async fn get_groups_by_owner_id(
11✔
555
    dbh: &Surreal<Client>,
556
    uid: usize,
557
) -> surrealdb::Result<Vec<Group>> {
558
    rocket::info!("get_groups_by_owner_id: '{uid}'");
22✔
559
    let mut response = dbh
22✔
560
        .query("SELECT * FROM group WHERE owner=$uid;")
561
        .bind(("uid", uid))
11✔
562
        .await?;
11✔
563

564
    let entries: Vec<Group> = response.take(0)?;
22✔
565

566
    Ok(entries)
11✔
567
}
568

569
pub async fn get_group_by_gid(
98✔
570
    dbh: &Surreal<Client>,
571
    gid: usize,
572
) -> surrealdb::Result<Option<Group>> {
573
    rocket::info!("get_group_by_gid: '{gid}'");
196✔
574
    let mut response = dbh
196✔
575
        .query("SELECT * FROM group WHERE gid=$gid;")
576
        .bind(("gid", gid))
98✔
577
        .await?;
98✔
578

579
    let entry: Option<Group> = response.take(0)?;
196✔
580

581
    if let Some(entry) = entry.as_ref() {
92✔
582
        rocket::info!("Group name: {}", entry.name);
92✔
583
    }
584

585
    Ok(entry)
98✔
586
}
587

588
pub async fn get_events(dbh: &Surreal<Client>) -> surrealdb::Result<Vec<Event>> {
30✔
589
    rocket::info!("get_events");
30✔
590
    let mut response = dbh.query("SELECT * FROM event;").await?;
45✔
591
    let entries: Vec<Event> = response.take(0)?;
30✔
592
    for ent in &entries {
49✔
593
        rocket::info!("event name {}", ent.title);
17✔
594
    }
595
    Ok(entries)
15✔
596
}
597

598
/// # Panics
599
///
600
/// Panics when there is an error
601
pub async fn increment(dbh: &Surreal<Client>, name: &str) -> surrealdb::Result<usize> {
536✔
602
    // TODO: do this only when creatig the database
603
    let _response = dbh
536✔
604
        .query("DEFINE INDEX counter_name ON TABLE counter COLUMNS name UNIQUE")
605
        .await?;
268✔
606

607
    let response = dbh
536✔
608
        .query(
609
            "
610
            INSERT INTO counter (name, count)
611
                VALUES ($name, $count) ON DUPLICATE KEY UPDATE count += 1;
612
        ",
613
        )
614
        .bind(("name", name))
268✔
615
        .bind(("count", 1_i32))
268✔
616
        .await?;
268✔
617

618
    let mut entries = response.check()?;
536✔
619
    let entries: Vec<Counter> = entries.take(0)?;
268✔
620
    // fetching the first (and hopefully only) entry
621
    let entry = entries.into_iter().next().unwrap();
268✔
622
    let id: usize = entry.count.try_into().unwrap();
268✔
623

624
    Ok(id)
268✔
625
}
626

627
pub async fn get_event_by_eid(
28✔
628
    dbh: &Surreal<Client>,
629
    eid: usize,
630
) -> surrealdb::Result<Option<Event>> {
631
    rocket::info!("get_event_by_eid: '{eid}'");
56✔
632
    let mut response = dbh
56✔
633
        .query("SELECT * FROM event WHERE eid=$eid;")
634
        .bind(("eid", eid))
28✔
635
        .await?;
28✔
636

637
    let entry: Option<Event> = response.take(0)?;
56✔
638

639
    if let Some(entry) = entry.as_ref() {
24✔
640
        rocket::info!("Event title: {}", entry.title);
24✔
641
    }
642

643
    Ok(entry)
28✔
644
}
645

646
pub async fn join_group(dbh: &Surreal<Client>, gid: usize, uid: usize) -> surrealdb::Result<()> {
4✔
647
    rocket::info!("user {} joins group: {}", uid, gid);
4✔
648

649
    let date: DateTime<Utc> = Utc::now();
2✔
650

651
    let membership = Membership {
652
        uid,
653
        gid,
654
        join_date: date,
655
        admin: false,
656
    };
657

658
    dbh.create(Resource::from("membership"))
2✔
659
        .content(membership)
2✔
660
        .await?;
2✔
661

662
    Ok(())
2✔
663
}
664

665
/// # Panics
666
///
667
/// Panics when it fails
668
pub async fn leave_group(dbh: &Surreal<Client>, gid: usize, uid: usize) -> surrealdb::Result<()> {
2✔
669
    rocket::info!("user {} leaves group: {}", uid, gid);
2✔
670

671
    dbh.query("DELETE membership WHERE uid=$uid AND gid=$gid")
1✔
672
        .bind(("uid", uid))
1✔
673
        .bind(("gid", gid))
1✔
674
        .await?
1✔
675
        .check()
676
        .unwrap();
677

678
    Ok(())
1✔
679
}
680

681
pub async fn get_membership(
8✔
682
    dbh: &Surreal<Client>,
683
    gid: usize,
684
    uid: usize,
685
) -> surrealdb::Result<Option<Membership>> {
686
    let mut response = dbh
16✔
687
        .query("SELECT * FROM membership WHERE gid=$gid AND uid=$uid;")
688
        .bind(("gid", gid))
8✔
689
        .bind(("uid", uid))
8✔
690
        .await?;
8✔
691

692
    let entry: Option<Membership> = response.take(0)?;
16✔
693

694
    Ok(entry)
8✔
695
}
696

697
/// # Panics
698
///
699
/// Panics when there is an error.
700
pub async fn get_all_rsvps_for_event(
10✔
701
    dbh: &Surreal<Client>,
702
    eid: usize,
703
) -> surrealdb::Result<Vec<(RSVP, User)>> {
704
    let mut response = dbh
20✔
705
        .query("SELECT * FROM rsvp WHERE eid=$eid;")
706
        .bind(("eid", eid))
10✔
707
        .await?;
10✔
708

709
    let entries: Vec<RSVP> = response.take(0)?;
20✔
710

UNCOV
711
    let mut people = vec![];
×
712
    for entry in entries {
16✔
713
        // We assume that each uid will have a user
714
        let user = get_user_by_id(dbh, entry.uid).await.unwrap().unwrap();
9✔
715
        people.push((entry, user));
3✔
716
    }
717

718
    Ok(people)
10✔
719
}
720

721
pub async fn get_rsvp(
12✔
722
    dbh: &Surreal<Client>,
723
    eid: usize,
724
    uid: usize,
725
) -> surrealdb::Result<Option<RSVP>> {
726
    let mut response = dbh
24✔
727
        .query("SELECT * FROM rsvp WHERE eid=$eid AND uid=$uid;")
728
        .bind(("eid", eid))
12✔
729
        .bind(("uid", uid))
12✔
730
        .await?;
12✔
731

732
    let entry: Option<RSVP> = response.take(0)?;
24✔
733

734
    Ok(entry)
12✔
735
}
736

737
pub async fn new_rsvp(
1✔
738
    dbh: &Surreal<Client>,
739
    eid: usize,
740
    uid: usize,
741
    status: bool,
742
) -> surrealdb::Result<()> {
743
    rocket::info!("user {} RSVP: {} status: {}", uid, eid, status);
2✔
744

745
    let date: DateTime<Utc> = Utc::now();
1✔
746

747
    let rsvp = RSVP {
748
        eid,
749
        uid,
750
        date,
751
        status,
752
    };
753

754
    dbh.create(Resource::from("rsvp")).content(rsvp).await?;
2✔
755

756
    Ok(())
1✔
757
}
758

759
pub async fn update_rsvp(
2✔
760
    dbh: &Surreal<Client>,
761
    eid: usize,
762
    uid: usize,
763
    status: bool,
764
) -> surrealdb::Result<()> {
765
    rocket::info!("user {} RSVP: {} status: {}", uid, eid, status);
4✔
766

767
    let date: DateTime<Utc> = Utc::now();
2✔
768

769
    dbh.query("UPDATE rsvp SET status=$status, date=$date WHERE uid=$uid AND eid=$eid")
2✔
770
        .bind(("status", status))
2✔
771
        .bind(("uid", uid))
2✔
772
        .bind(("eid", eid))
2✔
773
        .bind(("date", date))
2✔
774
        .await?;
2✔
775

776
    Ok(())
2✔
777
}
778

779
pub async fn audit(dbh: &Surreal<Client>, text: String) -> surrealdb::Result<()> {
122✔
780
    rocket::info!("audit {text}");
122✔
781

782
    let date: DateTime<Utc> = Utc::now();
61✔
783
    let entry = Audit { date, text };
61✔
784

785
    dbh.create(Resource::from("audit")).content(entry).await?;
122✔
786

787
    Ok(())
61✔
788
}
789

790
pub async fn get_audit(dbh: &Surreal<Client>) -> surrealdb::Result<Vec<Audit>> {
4✔
791
    rocket::info!("get_audits");
4✔
792
    let mut response = dbh.query("SELECT * FROM audit;").await?;
6✔
793
    let entries: Vec<Audit> = response.take(0)?;
4✔
794
    Ok(entries)
2✔
795
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc