1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! [`Repository`] Trait to define a database repository
mod_def!
use cratemod_def;
use cratePool;
use crateModel;
use ;
/// A trait that provides a standardized interface for database operations, implementing the Repository pattern.
///
/// This trait serves as a foundation for all repository implementations in the system,
/// offering both basic access to database connections and advanced batch processing capabilities.
/// It centralizes the logic for database access patterns and promotes consistent error handling
/// across the application.
///
/// # Type Parameters
///
/// * `M` - The model type that this repository manages. Must implement the [`Model`] trait.
///
/// # Design Philosophy
///
/// This trait follows several key design principles:
///
/// 1. **Separation of Concerns**: The repository isolates database access logic from business logic
/// 2. **Type Safety**: Uses generics and associated types to maintain compile-time type checking
/// 3. **Instrumentation Support**: Built-in tracing for debugging and monitoring
/// 4. **Extensibility**: Serves as a base for more specialized repository traits
///
/// # Core Methods
///
/// Repositories must implement:
///
/// ```no_compile
/// fn pool(&self) -> &Pool; // Access to database connection pool
/// ```
///
/// # Usage Example
///
/// Basic repository implementation:
/// ```rust
/// # use sqlx_utils::prelude::*;
/// # use sqlx_utils::types::Pool;
/// # struct User { id: i32, name: String }
/// # impl Model for User {
/// # type Id = i32;
/// # fn get_id(&self) -> Option<Self::Id> { Some(self.id) }
/// # }
///
/// struct UserRepository {
/// pool: Pool
/// }
///
/// impl Repository<User> for UserRepository {
/// fn pool(&self) -> &Pool {
/// &self.pool
/// }
/// }
///
/// // Adding specialized capabilities through extension traits
/// impl InsertableRepository<User> for UserRepository {
/// fn insert_query(user: &User) -> Query<'_> {
/// sqlx::query("INSERT INTO users (name) VALUES ($1)")
/// .bind(&user.name)
/// }
/// }
/// ```
///
/// # Error Handling
///
/// Repository methods return [`crate::Result<T>`], providing consistent error handling across
/// the application. This includes database errors, validation errors, and transactions errors.
///
/// # Implementation Notes
///
/// 1. The trait is intended to be extended by more specialized traits that provide
/// concrete CRUD operations (like [`InsertableRepository`], [`UpdatableRepository`], etc.)
/// 2. The static `repository_span()` method provides consistent tracing instrumentation
/// across all repositories
/// 3. Use the included macros ([`repository!`](crate::repository), [`repository_insert!`](crate::repository_insert), etc.) to reduce
/// boilerplate when implementing repositories