use crate::context::DjogiContext;
use crate::descriptor::PkType;
use crate::error::DjogiError;
use crate::primary_key::{PrimaryKey, PrimaryKeyDbGen, checked_count};
use crate::types::{HeerId, HeerIdDesc, RanjId, RanjIdDesc};
macro_rules! impl_heeranjid_pk {
(
$ty:ty,
$kind_tag:ident,
$sql_type:literal,
$default_sql:literal,
$single_sql:literal,
$batch_sql:literal $(,)?
) => {
impl PrimaryKey for $ty {
const __DJOGI_PK_SEAL: crate::primary_key::PkSealToken =
crate::__private::pk_seal::TOKEN;
const KIND: PkType = PkType::$kind_tag;
const SQL_TYPE: &'static str = $sql_type;
const DEFAULT_SQL: Option<&'static str> = Some($default_sql);
fn sentinel() -> Self {
<$ty>::ZERO
}
}
impl PrimaryKeyDbGen for $ty {
async fn generate(ctx: &mut DjogiContext) -> Result<Self, DjogiError> {
let row = ctx.query_one($single_sql, &[]).await?;
Ok(row.try_get::<_, $ty>(0)?)
}
async fn generate_many(
ctx: &mut DjogiContext,
n: usize,
) -> Result<Vec<Self>, DjogiError> {
let count = checked_count(n)?;
if count == 0 {
return Ok(Vec::new());
}
let rows = ctx.query_all($batch_sql, &[&count]).await?;
rows.into_iter()
.map(|row| row.try_get::<_, $ty>(0).map_err(DjogiError::from))
.collect()
}
}
};
}
impl_heeranjid_pk!(
HeerId,
HeerId,
"BIGINT",
"heerid_next()",
"SELECT heerid_next()",
"SELECT id FROM generate_ids(current_heer_node_id(), $1::integer, true)",
);
impl_heeranjid_pk!(
HeerIdDesc,
HeerIdDesc,
"BIGINT",
"heerid_next_desc()",
"SELECT heerid_next_desc()",
"SELECT heerid_to_desc(id) \
FROM generate_ids(current_heer_node_id(), $1::integer, true)",
);
impl_heeranjid_pk!(
RanjId,
RanjId,
"UUID",
"ranjid_next()",
"SELECT ranjid_next()",
"SELECT id FROM generate_ranjids(current_heer_ranj_node_id(), $1::integer, true)",
);
impl_heeranjid_pk!(
RanjIdDesc,
RanjIdDesc,
"UUID",
"ranjid_next_desc()",
"SELECT ranjid_next_desc()",
"SELECT ranjid_to_desc(id) \
FROM generate_ranjids(current_heer_ranj_node_id(), $1::integer, true)",
);
impl PrimaryKey for i32 {
const __DJOGI_PK_SEAL: crate::primary_key::PkSealToken = crate::__private::pk_seal::TOKEN;
const KIND: PkType = PkType::Serial;
const SQL_TYPE: &'static str = "INTEGER";
const DEFAULT_SQL: Option<&'static str> = None;
fn sentinel() -> Self {
0
}
}