use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use pylon_core::ir::SessionConfig;
use pylon_core::schema::SchemaDescriptor;
use pylon_value::DecodedValue;
use crate::error::Result;
use crate::exec;
use crate::query_arg::QueryArgs;
use crate::queryable::{Queryable, decode_optional_row, decode_row, decode_rows};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Isolation {
ReadUncommitted,
ReadCommitted,
RepeatableRead,
#[default]
Serializable,
}
impl Isolation {
pub(crate) fn as_str(self) -> &'static str {
match self {
Isolation::ReadUncommitted => "read_uncommitted",
Isolation::ReadCommitted => "read_committed",
Isolation::RepeatableRead => "repeatable_read",
Isolation::Serializable => "serializable",
}
}
}
pub struct Transaction {
pub(crate) inner: pylon_pgcon::PgTransaction,
pub(crate) schema: Arc<RwLock<SchemaDescriptor>>,
pub(crate) config: SessionConfig,
pub(crate) globals: Arc<HashMap<String, DecodedValue>>,
pub(crate) cache: Option<Arc<pylon_cache::Cache>>,
}
impl Transaction {
pub async fn query<R: Queryable, A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<Vec<R>> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
let values = exec::query(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await?;
decode_rows(values)
}
pub async fn query_single<R: Queryable, A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<Option<R>> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
let values = exec::query_single(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await?;
decode_optional_row(values)
}
pub async fn query_required_single<R: Queryable, A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<R> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
let values = exec::query_required_single(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await?;
decode_row(values)
}
pub async fn execute<A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<()> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
exec::execute(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await
}
pub async fn query_json<A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<String> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
exec::query_json(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await
}
pub async fn query_single_json<A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<Option<String>> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
exec::query_single_json(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await
}
pub async fn query_required_single_json<A: QueryArgs + ?Sized>(&self, pyql: &str, args: &A) -> Result<String> {
let params = args.to_params();
let schema = self.schema.read().unwrap().clone();
exec::query_required_single_json(
&self.inner,
pyql,
¶ms,
&schema,
&self.config,
&self.globals,
crate::cache::CacheAccess::evict_only(self.cache.as_deref()),
)
.await
}
}