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

0xmichalis / nftbk / 18536043780

15 Oct 2025 04:38PM UTC coverage: 36.511% (-0.2%) from 36.703%
18536043780

Pull #72

github

web-flow
Merge f69c32bfd into 95e6dd6dd
Pull Request #72: fix: enable subresource creation when the other exists for same NFTs

31 of 88 new or added lines in 4 files covered. (35.23%)

1 existing line in 1 file now uncovered.

1463 of 4007 relevant lines covered (36.51%)

6.14 hits per line

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

50.0
/src/server/database/trait.rs
1
use async_trait::async_trait;
2
use serde_json;
3
use sqlx;
4

5
use crate::server::database::{BackupTask, ExpiredBackup, PinRow, TokenWithPins};
6
use crate::TokenPinMapping;
7

8
/// Unified database trait that consolidates all database operations
9
#[async_trait]
10
pub trait Database {
11
    // Backup task operations
12
    #[allow(clippy::too_many_arguments)]
13
    async fn insert_backup_task(
14
        &self,
15
        task_id: &str,
16
        requestor: &str,
17
        nft_count: i32,
18
        tokens: &serde_json::Value,
19
        storage_mode: &str,
20
        archive_format: Option<&str>,
21
        retention_days: Option<u64>,
22
    ) -> Result<(), sqlx::Error>;
23

24
    async fn get_backup_task(&self, task_id: &str) -> Result<Option<BackupTask>, sqlx::Error>;
25

26
    async fn delete_backup_task(&self, task_id: &str) -> Result<(), sqlx::Error>;
27

28
    async fn get_incomplete_backup_tasks(&self) -> Result<Vec<BackupTask>, sqlx::Error>;
29

30
    async fn list_requestor_backup_tasks_paginated(
31
        &self,
32
        requestor: &str,
33
        include_tokens: bool,
34
        limit: i64,
35
        offset: i64,
36
    ) -> Result<(Vec<BackupTask>, u32), sqlx::Error>;
37

38
    async fn list_unprocessed_expired_backups(&self) -> Result<Vec<ExpiredBackup>, sqlx::Error>;
39

40
    // Backup task status and error operations
41
    async fn clear_backup_errors(&self, task_id: &str, scope: &str) -> Result<(), sqlx::Error>;
42

43
    async fn set_backup_error(&self, task_id: &str, error: &str) -> Result<(), sqlx::Error>;
44

45
    async fn set_error_logs(
46
        &self,
47
        task_id: &str,
48
        archive_error_log: Option<&str>,
49
        ipfs_error_log: Option<&str>,
50
    ) -> Result<(), sqlx::Error>;
51

52
    async fn update_archive_request_error_log(
53
        &self,
54
        task_id: &str,
55
        error_log: &str,
56
    ) -> Result<(), sqlx::Error>;
57

58
    async fn update_pin_request_error_log(
59
        &self,
60
        task_id: &str,
61
        error_log: &str,
62
    ) -> Result<(), sqlx::Error>;
63

64
    async fn set_archive_request_error(
65
        &self,
66
        task_id: &str,
67
        fatal_error: &str,
68
    ) -> Result<(), sqlx::Error>;
69

70
    async fn set_pin_request_error(
71
        &self,
72
        task_id: &str,
73
        fatal_error: &str,
74
    ) -> Result<(), sqlx::Error>;
75

76
    // Status update operations
77
    async fn update_archive_request_status(
78
        &self,
79
        task_id: &str,
80
        status: &str,
81
    ) -> Result<(), sqlx::Error>;
82

83
    async fn update_pin_request_status(
84
        &self,
85
        task_id: &str,
86
        status: &str,
87
    ) -> Result<(), sqlx::Error>;
88

89
    async fn update_backup_statuses(
90
        &self,
91
        task_id: &str,
92
        scope: &str,
93
        archive_status: &str,
94
        ipfs_status: &str,
95
    ) -> Result<(), sqlx::Error>;
96

97
    async fn update_archive_request_statuses(
98
        &self,
99
        task_ids: &[String],
100
        status: &str,
101
    ) -> Result<(), sqlx::Error>;
102

103
    // Upgrade operations
104
    async fn upgrade_backup_to_full(
105
        &self,
106
        task_id: &str,
107
        add_archive: bool,
108
        archive_format: Option<&str>,
109
        retention_days: Option<u64>,
110
    ) -> Result<(), sqlx::Error>;
111

112
    // Deletion operations
113
    async fn start_deletion(&self, task_id: &str) -> Result<(), sqlx::Error>;
114

115
    async fn start_archive_request_deletion(&self, task_id: &str) -> Result<(), sqlx::Error>;
116

117
    async fn start_pin_request_deletions(&self, task_id: &str) -> Result<(), sqlx::Error>;
118

119
    async fn complete_archive_request_deletion(&self, task_id: &str) -> Result<(), sqlx::Error>;
120

121
    async fn complete_pin_request_deletion(&self, task_id: &str) -> Result<(), sqlx::Error>;
122

123
    // Retry operations
124
    async fn retry_backup(
125
        &self,
126
        task_id: &str,
127
        scope: &str,
128
        retention_days: u64,
129
    ) -> Result<(), sqlx::Error>;
130

131
    // Pin operations
132
    async fn insert_pins_with_tokens(
133
        &self,
134
        task_id: &str,
135
        token_pin_mappings: &[TokenPinMapping],
136
    ) -> Result<(), sqlx::Error>;
137

138
    async fn get_pins_by_task_id(&self, task_id: &str) -> Result<Vec<PinRow>, sqlx::Error>;
139

140
    async fn get_active_pins(&self) -> Result<Vec<PinRow>, sqlx::Error>;
141

142
    async fn update_pin_statuses(&self, updates: &[(i64, String)]) -> Result<(), sqlx::Error>;
143

144
    // Pinned tokens operations
145
    async fn get_pinned_tokens_by_requestor(
146
        &self,
147
        requestor: &str,
148
        limit: i64,
149
        offset: i64,
150
    ) -> Result<(Vec<TokenWithPins>, u32), sqlx::Error>;
151

152
    async fn get_pinned_token_by_requestor(
153
        &self,
154
        requestor: &str,
155
        chain: &str,
156
        contract_address: &str,
157
        token_id: &str,
158
    ) -> Result<Option<TokenWithPins>, sqlx::Error>;
159
}
160

161
/// Configurable mock database implementation for testing
162
/// Each method can be configured to return specific responses or errors
163
#[derive(Default)]
164
pub struct MockDatabase {
165
    // Backup task operations
166
    pub insert_backup_task_error: Option<String>,
167
    pub get_backup_task_result: Option<BackupTask>,
168
    pub get_backup_task_error: Option<String>,
169
    pub delete_backup_task_error: Option<String>,
170
    pub get_incomplete_backup_tasks_result: Vec<BackupTask>,
171
    pub get_incomplete_backup_tasks_error: Option<String>,
172
    pub list_requestor_backup_tasks_paginated_result: (Vec<BackupTask>, u32),
173
    pub list_requestor_backup_tasks_paginated_error: Option<String>,
174
    pub list_unprocessed_expired_backups_result: Vec<ExpiredBackup>,
175
    pub list_unprocessed_expired_backups_error: Option<String>,
176

177
    // Backup task status and error operations
178
    pub clear_backup_errors_error: Option<String>,
179
    pub set_backup_error_error: Option<String>,
180
    pub set_error_logs_error: Option<String>,
181
    pub update_archive_request_error_log_error: Option<String>,
182
    pub update_pin_request_error_log_error: Option<String>,
183
    pub set_archive_request_error_error: Option<String>,
184
    pub set_pin_request_error_error: Option<String>,
185

186
    // Status update operations
187
    pub update_archive_request_status_error: Option<String>,
188
    pub update_pin_request_status_error: Option<String>,
189
    pub update_backup_statuses_error: Option<String>,
190
    pub update_archive_request_statuses_error: Option<String>,
191

192
    // Upgrade operations
193
    pub upgrade_backup_to_full_error: Option<String>,
194

195
    // Deletion operations
196
    pub start_deletion_error: Option<String>,
197
    pub start_archive_request_deletion_error: Option<String>,
198
    pub start_pin_request_deletions_error: Option<String>,
199
    pub complete_archive_request_deletion_error: Option<String>,
200
    pub complete_pin_request_deletion_error: Option<String>,
201

202
    // Retry operations
203
    pub retry_backup_error: Option<String>,
204

205
    // Pin operations
206
    pub insert_pins_with_tokens_error: Option<String>,
207
    pub get_pins_by_task_id_result: Vec<PinRow>,
208
    pub get_pins_by_task_id_error: Option<String>,
209
    pub get_active_pins_result: Vec<PinRow>,
210
    pub get_active_pins_error: Option<String>,
211
    pub update_pin_statuses_error: Option<String>,
212

213
    // Pinned tokens operations
214
    pub get_pinned_tokens_by_requestor_result: (Vec<TokenWithPins>, u32),
215
    pub get_pinned_tokens_by_requestor_error: Option<String>,
216
    pub get_pinned_token_by_requestor_result: Option<TokenWithPins>,
217
    pub get_pinned_token_by_requestor_error: Option<String>,
218

219
    // Call counters for verifying interactions in tests
220
    pub get_active_pins_calls: std::sync::Mutex<u32>,
221
    pub update_pin_statuses_calls: std::sync::Mutex<u32>,
222
    pub get_incomplete_backup_tasks_calls: std::sync::Mutex<u32>,
223
    pub set_backup_error_calls: std::sync::Mutex<u32>,
224
}
225

226
impl MockDatabase {
227
    // Configuration methods for backup task operations
228
    pub fn set_insert_backup_task_error(&mut self, error: Option<String>) {
×
229
        self.insert_backup_task_error = error;
×
230
    }
231

232
    pub fn set_get_backup_task_result(&mut self, result: Option<BackupTask>) {
22✔
233
        self.get_backup_task_result = result;
44✔
234
    }
235

236
    pub fn set_get_backup_task_error(&mut self, error: Option<String>) {
4✔
237
        self.get_backup_task_error = error;
8✔
238
    }
239

240
    pub fn set_delete_backup_task_error(&mut self, error: Option<String>) {
1✔
241
        self.delete_backup_task_error = error;
2✔
242
    }
243

244
    pub fn set_get_incomplete_backup_tasks_result(&mut self, result: Vec<BackupTask>) {
4✔
245
        self.get_incomplete_backup_tasks_result = result;
8✔
246
    }
247

248
    pub fn set_get_incomplete_backup_tasks_error(&mut self, error: Option<String>) {
1✔
249
        self.get_incomplete_backup_tasks_error = error;
2✔
250
    }
251

252
    pub fn set_list_requestor_backup_tasks_paginated_result(
1✔
253
        &mut self,
254
        result: (Vec<BackupTask>, u32),
255
    ) {
256
        self.list_requestor_backup_tasks_paginated_result = result;
2✔
257
    }
258

259
    pub fn set_list_requestor_backup_tasks_paginated_error(&mut self, error: Option<String>) {
1✔
260
        self.list_requestor_backup_tasks_paginated_error = error;
2✔
261
    }
262

263
    pub fn set_list_unprocessed_expired_backups_result(&mut self, result: Vec<ExpiredBackup>) {
×
264
        self.list_unprocessed_expired_backups_result = result;
×
265
    }
266

267
    pub fn set_list_unprocessed_expired_backups_error(&mut self, error: Option<String>) {
×
268
        self.list_unprocessed_expired_backups_error = error;
×
269
    }
270

271
    // Configuration methods for backup task status and error operations
272
    pub fn set_clear_backup_errors_error(&mut self, error: Option<String>) {
×
273
        self.clear_backup_errors_error = error;
×
274
    }
275

276
    pub fn set_set_backup_error_error(&mut self, error: Option<String>) {
×
277
        self.set_backup_error_error = error;
×
278
    }
279

280
    pub fn set_set_error_logs_error(&mut self, error: Option<String>) {
×
281
        self.set_error_logs_error = error;
×
282
    }
283

284
    pub fn set_update_archive_request_error_log_error(&mut self, error: Option<String>) {
×
285
        self.update_archive_request_error_log_error = error;
×
286
    }
287

288
    pub fn set_update_pin_request_error_log_error(&mut self, error: Option<String>) {
×
289
        self.update_pin_request_error_log_error = error;
×
290
    }
291

292
    pub fn set_set_archive_request_error_error(&mut self, error: Option<String>) {
×
293
        self.set_archive_request_error_error = error;
×
294
    }
295

296
    pub fn set_set_pin_request_error_error(&mut self, error: Option<String>) {
×
297
        self.set_pin_request_error_error = error;
×
298
    }
299

300
    // Configuration methods for status update operations
301
    pub fn set_update_archive_request_status_error(&mut self, error: Option<String>) {
×
302
        self.update_archive_request_status_error = error;
×
303
    }
304

305
    pub fn set_update_pin_request_status_error(&mut self, error: Option<String>) {
×
306
        self.update_pin_request_status_error = error;
×
307
    }
308

309
    pub fn set_update_backup_statuses_error(&mut self, error: Option<String>) {
×
310
        self.update_backup_statuses_error = error;
×
311
    }
312

313
    pub fn set_update_archive_request_statuses_error(&mut self, error: Option<String>) {
×
314
        self.update_archive_request_statuses_error = error;
×
315
    }
316

317
    // Configuration methods for upgrade operations
NEW
318
    pub fn set_upgrade_backup_to_full_error(&mut self, error: Option<String>) {
×
NEW
319
        self.upgrade_backup_to_full_error = error;
×
320
    }
321

322
    // Configuration methods for deletion operations
323
    pub fn set_start_deletion_error(&mut self, error: Option<String>) {
1✔
324
        self.start_deletion_error = error;
2✔
325
    }
326

327
    pub fn set_start_archive_request_deletion_error(&mut self, error: Option<String>) {
×
328
        self.start_archive_request_deletion_error = error;
×
329
    }
330

331
    pub fn set_start_pin_request_deletions_error(&mut self, error: Option<String>) {
×
332
        self.start_pin_request_deletions_error = error;
×
333
    }
334

335
    pub fn set_complete_archive_request_deletion_error(&mut self, error: Option<String>) {
×
336
        self.complete_archive_request_deletion_error = error;
×
337
    }
338

339
    pub fn set_complete_pin_request_deletion_error(&mut self, error: Option<String>) {
×
340
        self.complete_pin_request_deletion_error = error;
×
341
    }
342

343
    // Configuration methods for retry operations
344
    pub fn set_retry_backup_error(&mut self, error: Option<String>) {
×
345
        self.retry_backup_error = error;
×
346
    }
347

348
    // Configuration methods for pin operations
349
    pub fn set_insert_pins_with_tokens_error(&mut self, error: Option<String>) {
×
350
        self.insert_pins_with_tokens_error = error;
×
351
    }
352

353
    pub fn set_get_pins_by_task_id_result(&mut self, result: Vec<PinRow>) {
×
354
        self.get_pins_by_task_id_result = result;
×
355
    }
356

357
    pub fn set_get_pins_by_task_id_error(&mut self, error: Option<String>) {
×
358
        self.get_pins_by_task_id_error = error;
×
359
    }
360

361
    pub fn set_get_active_pins_result(&mut self, result: Vec<PinRow>) {
10✔
362
        self.get_active_pins_result = result;
20✔
363
    }
364

365
    pub fn set_get_active_pins_error(&mut self, error: Option<String>) {
1✔
366
        self.get_active_pins_error = error;
2✔
367
    }
368

369
    pub fn set_update_pin_statuses_error(&mut self, error: Option<String>) {
1✔
370
        self.update_pin_statuses_error = error;
2✔
371
    }
372

373
    // Configuration methods for pinned tokens operations
374
    pub fn set_get_pinned_tokens_by_requestor_result(&mut self, result: (Vec<TokenWithPins>, u32)) {
2✔
375
        self.get_pinned_tokens_by_requestor_result = result;
4✔
376
    }
377

378
    pub fn set_get_pinned_tokens_by_requestor_error(&mut self, error: Option<String>) {
1✔
379
        self.get_pinned_tokens_by_requestor_error = error;
2✔
380
    }
381

382
    pub fn set_get_pinned_token_by_requestor_result(&mut self, result: Option<TokenWithPins>) {
×
383
        self.get_pinned_token_by_requestor_result = result;
×
384
    }
385

386
    pub fn set_get_pinned_token_by_requestor_error(&mut self, error: Option<String>) {
×
387
        self.get_pinned_token_by_requestor_error = error;
×
388
    }
389

390
    // Call counter getters
391
    pub fn get_active_pins_calls(&self) -> u32 {
12✔
392
        *self.get_active_pins_calls.lock().unwrap()
24✔
393
    }
394

395
    pub fn get_update_pin_statuses_calls(&self) -> u32 {
12✔
396
        *self.update_pin_statuses_calls.lock().unwrap()
24✔
397
    }
398

399
    pub fn get_get_incomplete_backup_tasks_calls(&self) -> u32 {
×
400
        *self.get_incomplete_backup_tasks_calls.lock().unwrap()
×
401
    }
402

403
    pub fn get_set_backup_error_calls(&self) -> u32 {
×
404
        *self.set_backup_error_calls.lock().unwrap()
×
405
    }
406
}
407

408
#[async_trait]
409
impl Database for MockDatabase {
410
    // Backup task operations
411
    async fn insert_backup_task(
412
        &self,
413
        _task_id: &str,
414
        _requestor: &str,
415
        _nft_count: i32,
416
        _tokens: &serde_json::Value,
417
        _storage_mode: &str,
418
        _archive_format: Option<&str>,
419
        _retention_days: Option<u64>,
420
    ) -> Result<(), sqlx::Error> {
421
        if let Some(error) = &self.insert_backup_task_error {
7✔
422
            Err(sqlx::Error::Configuration(error.clone().into()))
423
        } else {
424
            Ok(())
7✔
425
        }
426
    }
427

428
    async fn get_backup_task(&self, _task_id: &str) -> Result<Option<BackupTask>, sqlx::Error> {
68✔
429
        if let Some(error) = &self.get_backup_task_error {
38✔
430
            Err(sqlx::Error::Configuration(error.clone().into()))
431
        } else {
432
            Ok(self.get_backup_task_result.clone())
30✔
433
        }
434
    }
435

436
    async fn delete_backup_task(&self, _task_id: &str) -> Result<(), sqlx::Error> {
8✔
437
        if let Some(error) = &self.delete_backup_task_error {
5✔
438
            Err(sqlx::Error::Configuration(error.clone().into()))
439
        } else {
440
            Ok(())
3✔
441
        }
442
    }
443

444
    async fn get_incomplete_backup_tasks(&self) -> Result<Vec<BackupTask>, sqlx::Error> {
10✔
445
        *self.get_incomplete_backup_tasks_calls.lock().unwrap() += 1;
10✔
446
        if let Some(error) = &self.get_incomplete_backup_tasks_error {
6✔
447
            Err(sqlx::Error::Configuration(error.clone().into()))
448
        } else {
449
            Ok(self.get_incomplete_backup_tasks_result.clone())
4✔
450
        }
451
    }
452

453
    async fn list_requestor_backup_tasks_paginated(
454
        &self,
455
        _requestor: &str,
456
        _include_tokens: bool,
457
        limit: i64,
458
        offset: i64,
459
    ) -> Result<(Vec<BackupTask>, u32), sqlx::Error> {
460
        if let Some(error) = &self.list_requestor_backup_tasks_paginated_error {
3✔
461
            Err(sqlx::Error::Configuration(error.clone().into()))
462
        } else {
463
            let (all_records, total_count) = &self.list_requestor_backup_tasks_paginated_result;
3✔
464
            let start = offset.max(0) as usize;
2✔
465
            let end = (start + limit.max(0) as usize).min(all_records.len());
6✔
466
            let page = if start < all_records.len() {
3✔
467
                all_records[start..end].to_vec()
3✔
468
            } else {
469
                Vec::new()
×
470
            };
471
            Ok((page, *total_count))
1✔
472
        }
473
    }
474

475
    async fn list_unprocessed_expired_backups(&self) -> Result<Vec<ExpiredBackup>, sqlx::Error> {
×
476
        if let Some(error) = &self.list_unprocessed_expired_backups_error {
×
477
            Err(sqlx::Error::Configuration(error.clone().into()))
×
478
        } else {
479
            Ok(self.list_unprocessed_expired_backups_result.clone())
×
480
        }
481
    }
482

483
    // Backup task status and error operations
484
    async fn clear_backup_errors(&self, _task_id: &str, _scope: &str) -> Result<(), sqlx::Error> {
8✔
485
        if let Some(error) = &self.clear_backup_errors_error {
4✔
486
            Err(sqlx::Error::Configuration(error.clone().into()))
487
        } else {
488
            Ok(())
4✔
489
        }
490
    }
491

492
    async fn set_backup_error(&self, _task_id: &str, _error: &str) -> Result<(), sqlx::Error> {
2✔
493
        *self.set_backup_error_calls.lock().unwrap() += 1;
2✔
494
        if let Some(error) = &self.set_backup_error_error {
1✔
495
            Err(sqlx::Error::Configuration(error.clone().into()))
496
        } else {
497
            Ok(())
1✔
498
        }
499
    }
500

501
    async fn set_error_logs(
502
        &self,
503
        _task_id: &str,
504
        _archive_error_log: Option<&str>,
505
        _ipfs_error_log: Option<&str>,
506
    ) -> Result<(), sqlx::Error> {
507
        if let Some(error) = &self.set_error_logs_error {
1✔
508
            Err(sqlx::Error::Configuration(error.clone().into()))
509
        } else {
510
            Ok(())
1✔
511
        }
512
    }
513

514
    async fn update_archive_request_error_log(
515
        &self,
516
        _task_id: &str,
517
        _error_log: &str,
518
    ) -> Result<(), sqlx::Error> {
519
        if let Some(error) = &self.update_archive_request_error_log_error {
1✔
520
            Err(sqlx::Error::Configuration(error.clone().into()))
521
        } else {
522
            Ok(())
1✔
523
        }
524
    }
525

526
    async fn update_pin_request_error_log(
527
        &self,
528
        _task_id: &str,
529
        _error_log: &str,
530
    ) -> Result<(), sqlx::Error> {
531
        if let Some(error) = &self.update_pin_request_error_log_error {
1✔
532
            Err(sqlx::Error::Configuration(error.clone().into()))
533
        } else {
534
            Ok(())
1✔
535
        }
536
    }
537

538
    async fn set_archive_request_error(
539
        &self,
540
        _task_id: &str,
541
        _fatal_error: &str,
542
    ) -> Result<(), sqlx::Error> {
543
        if let Some(error) = &self.set_archive_request_error_error {
×
544
            Err(sqlx::Error::Configuration(error.clone().into()))
×
545
        } else {
546
            Ok(())
×
547
        }
548
    }
549

550
    async fn set_pin_request_error(
551
        &self,
552
        _task_id: &str,
553
        _fatal_error: &str,
554
    ) -> Result<(), sqlx::Error> {
555
        if let Some(error) = &self.set_pin_request_error_error {
×
556
            Err(sqlx::Error::Configuration(error.clone().into()))
×
557
        } else {
558
            Ok(())
×
559
        }
560
    }
561

562
    // Status update operations
563
    async fn update_archive_request_status(
564
        &self,
565
        _task_id: &str,
566
        _status: &str,
567
    ) -> Result<(), sqlx::Error> {
568
        if let Some(error) = &self.update_archive_request_status_error {
×
569
            Err(sqlx::Error::Configuration(error.clone().into()))
×
570
        } else {
571
            Ok(())
×
572
        }
573
    }
574

575
    async fn update_pin_request_status(
576
        &self,
577
        _task_id: &str,
578
        _status: &str,
579
    ) -> Result<(), sqlx::Error> {
580
        if let Some(error) = &self.update_pin_request_status_error {
×
581
            Err(sqlx::Error::Configuration(error.clone().into()))
×
582
        } else {
583
            Ok(())
×
584
        }
585
    }
586

587
    async fn update_backup_statuses(
588
        &self,
589
        _task_id: &str,
590
        _scope: &str,
591
        _archive_status: &str,
592
        _ipfs_status: &str,
593
    ) -> Result<(), sqlx::Error> {
594
        if let Some(error) = &self.update_backup_statuses_error {
×
595
            Err(sqlx::Error::Configuration(error.clone().into()))
×
596
        } else {
597
            Ok(())
×
598
        }
599
    }
600

601
    async fn update_archive_request_statuses(
602
        &self,
603
        _task_ids: &[String],
604
        _status: &str,
605
    ) -> Result<(), sqlx::Error> {
606
        if let Some(error) = &self.update_archive_request_statuses_error {
×
607
            Err(sqlx::Error::Configuration(error.clone().into()))
×
608
        } else {
609
            Ok(())
×
610
        }
611
    }
612

613
    async fn upgrade_backup_to_full(
614
        &self,
615
        _task_id: &str,
616
        _add_archive: bool,
617
        _archive_format: Option<&str>,
618
        _retention_days: Option<u64>,
619
    ) -> Result<(), sqlx::Error> {
NEW
620
        if let Some(error) = &self.upgrade_backup_to_full_error {
×
621
            Err(sqlx::Error::Configuration(error.clone().into()))
622
        } else {
NEW
623
            Ok(())
×
624
        }
625
    }
626

627
    // Deletion operations
628
    async fn start_deletion(&self, _task_id: &str) -> Result<(), sqlx::Error> {
8✔
629
        if let Some(error) = &self.start_deletion_error {
5✔
630
            Err(sqlx::Error::Configuration(error.clone().into()))
631
        } else {
632
            Ok(())
3✔
633
        }
634
    }
635

636
    async fn start_archive_request_deletion(&self, _task_id: &str) -> Result<(), sqlx::Error> {
2✔
637
        if let Some(error) = &self.start_archive_request_deletion_error {
1✔
638
            Err(sqlx::Error::Configuration(error.clone().into()))
639
        } else {
640
            Ok(())
1✔
641
        }
642
    }
643

644
    async fn start_pin_request_deletions(&self, _task_id: &str) -> Result<(), sqlx::Error> {
2✔
645
        if let Some(error) = &self.start_pin_request_deletions_error {
1✔
646
            Err(sqlx::Error::Configuration(error.clone().into()))
647
        } else {
648
            Ok(())
1✔
649
        }
650
    }
651

652
    async fn complete_archive_request_deletion(&self, _task_id: &str) -> Result<(), sqlx::Error> {
2✔
653
        if let Some(error) = &self.complete_archive_request_deletion_error {
1✔
654
            Err(sqlx::Error::Configuration(error.clone().into()))
655
        } else {
656
            Ok(())
1✔
657
        }
658
    }
659

660
    async fn complete_pin_request_deletion(&self, _task_id: &str) -> Result<(), sqlx::Error> {
2✔
661
        if let Some(error) = &self.complete_pin_request_deletion_error {
1✔
662
            Err(sqlx::Error::Configuration(error.clone().into()))
663
        } else {
664
            Ok(())
1✔
665
        }
666
    }
667

668
    // Retry operations
669
    async fn retry_backup(
670
        &self,
671
        _task_id: &str,
672
        _scope: &str,
673
        _retention_days: u64,
674
    ) -> Result<(), sqlx::Error> {
675
        if let Some(error) = &self.retry_backup_error {
2✔
676
            Err(sqlx::Error::Configuration(error.clone().into()))
677
        } else {
678
            Ok(())
2✔
679
        }
680
    }
681

682
    // Pin operations
683
    async fn insert_pins_with_tokens(
684
        &self,
685
        _task_id: &str,
686
        _token_pin_mappings: &[TokenPinMapping],
687
    ) -> Result<(), sqlx::Error> {
688
        if let Some(error) = &self.insert_pins_with_tokens_error {
×
689
            Err(sqlx::Error::Configuration(error.clone().into()))
×
690
        } else {
691
            Ok(())
×
692
        }
693
    }
694

695
    async fn get_pins_by_task_id(&self, _task_id: &str) -> Result<Vec<PinRow>, sqlx::Error> {
×
696
        if let Some(error) = &self.get_pins_by_task_id_error {
×
697
            Err(sqlx::Error::Configuration(error.clone().into()))
×
698
        } else {
699
            Ok(self.get_pins_by_task_id_result.clone())
×
700
        }
701
    }
702

703
    async fn get_active_pins(&self) -> Result<Vec<PinRow>, sqlx::Error> {
24✔
704
        *self.get_active_pins_calls.lock().unwrap() += 1;
24✔
705
        if let Some(error) = &self.get_active_pins_error {
13✔
706
            Err(sqlx::Error::Configuration(error.clone().into()))
707
        } else {
708
            Ok(self.get_active_pins_result.clone())
11✔
709
        }
710
    }
711

712
    async fn update_pin_statuses(&self, _updates: &[(i64, String)]) -> Result<(), sqlx::Error> {
12✔
713
        *self.update_pin_statuses_calls.lock().unwrap() += 1;
12✔
714
        if let Some(error) = &self.update_pin_statuses_error {
7✔
715
            Err(sqlx::Error::Configuration(error.clone().into()))
716
        } else {
717
            Ok(())
5✔
718
        }
719
    }
720

721
    // Pinned tokens operations
722
    async fn get_pinned_tokens_by_requestor(
723
        &self,
724
        _requestor: &str,
725
        _limit: i64,
726
        _offset: i64,
727
    ) -> Result<(Vec<TokenWithPins>, u32), sqlx::Error> {
728
        if let Some(error) = &self.get_pinned_tokens_by_requestor_error {
4✔
729
            Err(sqlx::Error::Configuration(error.clone().into()))
730
        } else {
731
            Ok(self.get_pinned_tokens_by_requestor_result.clone())
2✔
732
        }
733
    }
734

735
    async fn get_pinned_token_by_requestor(
736
        &self,
737
        _requestor: &str,
738
        _chain: &str,
739
        _contract_address: &str,
740
        _token_id: &str,
741
    ) -> Result<Option<TokenWithPins>, sqlx::Error> {
742
        if let Some(error) = &self.get_pinned_token_by_requestor_error {
×
743
            Err(sqlx::Error::Configuration(error.clone().into()))
×
744
        } else {
745
            Ok(self.get_pinned_token_by_requestor_result.clone())
×
746
        }
747
    }
748
}
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