systemprompt_database/repository/
change_context.rs1use std::sync::Arc;
23
24use async_trait::async_trait;
25use sqlx::{PgConnection, PgPool};
26use systemprompt_traits::{ChangeActor, ChangeSource, ConfigVersionSource, RepositoryError};
27
28use crate::DbPool;
29
30pub type PlaneTransaction = sqlx::Transaction<'static, sqlx::Postgres>;
31
32pub async fn with_change_context(
33 conn: &mut PgConnection,
34 actor: &ChangeActor,
35 reason: Option<&str>,
36 source: &ChangeSource,
37) -> Result<(), RepositoryError> {
38 let source = source.to_string();
39 sqlx::query!(
40 "SELECT set_config('systemprompt.actor', $1, true) AS actor, \
41 set_config('systemprompt.reason', $2, true) AS reason, \
42 set_config('systemprompt.source', $3, true) AS source",
43 actor.label(),
44 reason.unwrap_or_default(),
45 source,
46 )
47 .fetch_one(conn)
48 .await?;
49 Ok(())
50}
51
52#[derive(Debug, Clone)]
53pub struct PgConfigVersion {
54 pool: Arc<PgPool>,
55}
56
57impl PgConfigVersion {
58 #[must_use]
59 pub fn new(db: &DbPool) -> Self {
60 Self {
61 pool: db.write_pool(),
62 }
63 }
64}
65
66#[async_trait]
67impl ConfigVersionSource for PgConfigVersion {
68 async fn current_version(&self) -> Result<i64, RepositoryError> {
69 let version = sqlx::query_scalar!("SELECT version FROM config_version WHERE id = 1")
70 .fetch_optional(&*self.pool)
71 .await?;
72 Ok(version.unwrap_or(0))
73 }
74}