rovenue/cache/
exposure.rs1use std::sync::Arc;
2
3use rusqlite::params;
4
5use super::store::CacheStore;
6use crate::error::RovenueResult;
7
8pub struct ExposureRepo {
12 store: Arc<CacheStore>,
13}
14
15impl ExposureRepo {
16 pub fn new(store: Arc<CacheStore>) -> Self {
17 Self { store }
18 }
19
20 pub fn is_exposed(
21 &self,
22 user_scope: &str,
23 experiment_id: &str,
24 variant_id: &str,
25 ) -> RovenueResult<bool> {
26 self.store.with_conn(|c| {
27 let mut stmt = c.prepare(
28 "SELECT 1 FROM experiment_exposure
29 WHERE user_scope = ?1 AND experiment_id = ?2 AND variant_id = ?3",
30 )?;
31 let mut rows = stmt.query(params![user_scope, experiment_id, variant_id])?;
32 Ok(rows.next()?.is_some())
33 })
34 }
35
36 pub fn mark(
37 &self,
38 user_scope: &str,
39 experiment_id: &str,
40 variant_id: &str,
41 exposed_at_ms: u64,
42 ) -> RovenueResult<()> {
43 self.store.with_conn(|c| {
44 c.execute(
45 "INSERT OR IGNORE INTO experiment_exposure
46 (user_scope, experiment_id, variant_id, exposed_at_ms)
47 VALUES (?1, ?2, ?3, ?4)",
48 params![user_scope, experiment_id, variant_id, exposed_at_ms as i64],
49 )?;
50 Ok(())
51 })
52 }
53}