zino_orm/
pool.rs

1use super::DatabasePool;
2use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed};
3
4/// A database connection pool with metadata.
5#[derive(Debug)]
6pub struct ConnectionPool<P = DatabasePool> {
7    /// Name.
8    name: &'static str,
9    /// Database.
10    database: &'static str,
11    /// Pool.
12    pool: P,
13    /// Availability.
14    available: AtomicBool,
15    /// Missed count.
16    missed_count: AtomicUsize,
17    /// Auto migration.
18    auto_migration: AtomicBool,
19}
20
21impl<P> ConnectionPool<P> {
22    /// Creates a new instance.
23    #[inline]
24    pub fn new(name: &'static str, database: &'static str, pool: P) -> Self {
25        Self {
26            name,
27            database,
28            pool,
29            available: AtomicBool::new(true),
30            missed_count: AtomicUsize::new(0),
31            auto_migration: AtomicBool::new(true),
32        }
33    }
34
35    /// Returns `true` if the connection pool is available.
36    #[inline]
37    pub fn is_available(&self) -> bool {
38        self.available.load(Relaxed)
39    }
40
41    /// Stores the value into the availability of the connection pool.
42    #[inline]
43    pub fn store_availability(&self, available: bool) {
44        self.available.store(available, Relaxed);
45        if available {
46            self.reset_missed_count();
47        } else {
48            self.increment_missed_count();
49        }
50    }
51
52    /// Disables auto migration.
53    #[inline]
54    pub fn disable_auto_migration(&self) {
55        self.auto_migration.store(false, Relaxed);
56    }
57
58    /// Returns the number of missed count.
59    #[inline]
60    pub fn missed_count(&self) -> usize {
61        self.missed_count.load(Relaxed)
62    }
63
64    /// Increments the missed count by 1.
65    #[inline]
66    pub fn increment_missed_count(&self) {
67        self.missed_count.fetch_add(1, Relaxed);
68    }
69
70    /// Resets the number of missed count.
71    #[inline]
72    pub fn reset_missed_count(&self) {
73        self.missed_count.store(0, Relaxed);
74    }
75
76    /// Returns `true` if the connection pool is retryable to connect.
77    #[inline]
78    pub fn is_retryable(&self) -> bool {
79        let missed_count = self.missed_count();
80        missed_count > 2 && missed_count.is_power_of_two()
81    }
82
83    /// Returns `true` if the connection pool enables auto migration.
84    #[inline]
85    pub fn auto_migration(&self) -> bool {
86        self.auto_migration.load(Relaxed)
87    }
88
89    /// Returns the name.
90    #[inline]
91    pub fn name(&self) -> &'static str {
92        self.name
93    }
94
95    /// Returns the database.
96    #[inline]
97    pub fn database(&self) -> &'static str {
98        self.database
99    }
100
101    /// Returns a reference to the pool.
102    #[inline]
103    pub fn pool(&self) -> &P {
104        &self.pool
105    }
106}