Skip to content

brokkr-broker::dal::templates

Rust

Data Access Layer for Stack Template operations.

This module provides functionality to interact with the database for Stack Template-related operations, including creating, retrieving, listing, and managing template versions.

pub

Data Access Layer for Stack Template operations.

Name Type Description
dal &'a DAL Reference to the main DAL instance.

pub

fn create(
&self,
new_template: &NewStackTemplate,
) -> Result<StackTemplate, diesel::result::Error>

Creates a new stack template in the database.

Parameters:

Name Type Description
new_template &NewStackTemplate A reference to the NewStackTemplate struct containing the template details.

Returns:

Returns a Result containing the created StackTemplate on success, or a diesel::result::Error on failure.

Source
pub fn create(
&self,
new_template: &NewStackTemplate,
) -> Result<StackTemplate, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::insert_into(stack_templates::table)
.values(new_template)
.get_result(conn)
}

pub

fn create_new_version(
&self,
generator_id: Option<Uuid>,
name: String,
description: Option<String>,
template_content: String,
parameters_schema: String,
) -> Result<StackTemplate, diesel::result::Error>

Creates a new version of an existing template.

This method automatically determines the next version number based on the existing versions for the given generator_id and name combination.

Parameters:

Name Type Description
generator_id Option<Uuid> Optional generator ID. None for system templates.
name String Name of the template.
description Option<String> Optional description.
template_content String The Tera template content.
parameters_schema String JSON Schema for parameter validation.

Returns:

Returns a Result containing the created StackTemplate on success, or a diesel::result::Error on failure.

Source
pub fn create_new_version(
&self,
generator_id: Option<Uuid>,
name: String,
description: Option<String>,
template_content: String,
parameters_schema: String,
) -> Result<StackTemplate, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
// Get the current max version for this template name and generator
let max_version: Option<i32> = match generator_id {
Some(gid) => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(&name))
.filter(stack_templates::generator_id.eq(Some(gid)))
.select(diesel::dsl::max(stack_templates::version))
.first(conn)?,
None => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(&name))
.filter(stack_templates::generator_id.is_null())
.select(diesel::dsl::max(stack_templates::version))
.first(conn)?,
};
let next_version = max_version.unwrap_or(0) + 1;
let new_template = NewStackTemplate::new(
generator_id,
name,
description,
next_version,
template_content,
parameters_schema,
)
.map_err(|e| diesel::result::Error::QueryBuilderError(e.into()))?;
diesel::insert_into(stack_templates::table)
.values(&new_template)
.get_result(conn)
}

pub

fn get(
&self,
template_id: Uuid,
) -> Result<Option<StackTemplate>, diesel::result::Error>

Retrieves a non-deleted stack template by its UUID.

Parameters:

Name Type Description
template_id Uuid The UUID of the template to retrieve.

Returns:

Returns a Result containing an Option if found, or a diesel::result::Error on failure.

Source
pub fn get(&self, template_id: Uuid) -> Result<Option<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::id.eq(template_id))
.filter(stack_templates::deleted_at.is_null())
.first(conn)
.optional()
}

pub

fn get_including_deleted(
&self,
template_id: Uuid,
) -> Result<Option<StackTemplate>, diesel::result::Error>

Retrieves a stack template by its UUID, including deleted templates.

Parameters:

Name Type Description
template_id Uuid The UUID of the template to retrieve.

Returns:

Returns a Result containing an Option if found, or a diesel::result::Error on failure.

Source
pub fn get_including_deleted(
&self,
template_id: Uuid,
) -> Result<Option<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::id.eq(template_id))
.first(conn)
.optional()
}

pub

fn list(&self) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all non-deleted stack templates from the database.

Returns:

Returns a Result containing a Vec of all non-deleted StackTemplates on success, or a diesel::result::Error on failure.

Source
pub fn list(&self) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.load::<StackTemplate>(conn)
}

pub

fn list_all(&self) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all stack templates from the database, including deleted ones.

Returns:

Returns a Result containing a Vec of all StackTemplates on success, or a diesel::result::Error on failure.

Source
pub fn list_all(&self) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table.load::<StackTemplate>(conn)
}

pub

fn list_by_generator(
&self,
generator_id: Uuid,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all non-deleted stack templates for a specific generator.

Parameters:

Name Type Description
generator_id Uuid The UUID of the generator to filter by.

Returns:

Returns a Result containing a Vec of StackTemplates belonging to the generator, or a diesel::result::Error on failure.

Source
pub fn list_by_generator(
&self,
generator_id: Uuid,
) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::generator_id.eq(Some(generator_id)))
.load::<StackTemplate>(conn)
}

pub

fn get_latest_version(
&self,
generator_id: Option<Uuid>,
name: &str,
) -> Result<Option<StackTemplate>, diesel::result::Error>

Gets the latest version of a template by name and generator_id.

Parameters:

Name Type Description
generator_id Option<Uuid> Optional generator ID. None for system templates.
name &str Name of the template.

Returns:

Returns a Result containing an Option with the highest version, or a diesel::result::Error on failure.

Source
pub fn get_latest_version(
&self,
generator_id: Option<Uuid>,
name: &str,
) -> Result<Option<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
match generator_id {
Some(gid) => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(name))
.filter(stack_templates::generator_id.eq(Some(gid)))
.order(stack_templates::version.desc())
.first(conn)
.optional(),
None => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(name))
.filter(stack_templates::generator_id.is_null())
.order(stack_templates::version.desc())
.first(conn)
.optional(),
}
}

pub

fn list_versions(
&self,
generator_id: Option<Uuid>,
name: &str,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all versions of a template by name and generator_id.

Parameters:

Name Type Description
generator_id Option<Uuid> Optional generator ID. None for system templates.
name &str Name of the template.

Returns:

Returns a Result containing a Vec of all versions of the template, ordered by version descending.

Source
pub fn list_versions(
&self,
generator_id: Option<Uuid>,
name: &str,
) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
match generator_id {
Some(gid) => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(name))
.filter(stack_templates::generator_id.eq(Some(gid)))
.order(stack_templates::version.desc())
.load::<StackTemplate>(conn),
None => stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::name.eq(name))
.filter(stack_templates::generator_id.is_null())
.order(stack_templates::version.desc())
.load::<StackTemplate>(conn),
}
}

pub

fn list_for_generator(
&self,
generator_id: Uuid,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all non-deleted templates for a specific generator.

Parameters:

Name Type Description
generator_id Uuid The UUID of the generator.

Returns:

Returns a Result containing a Vec of templates for the generator.

Source
pub fn list_for_generator(
&self,
generator_id: Uuid,
) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::generator_id.eq(Some(generator_id)))
.load::<StackTemplate>(conn)
}

pub

fn list_system_templates(
&self,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Lists all non-deleted system templates (generator_id IS NULL).

Returns:

Returns a Result containing a Vec of system templates.

Source
pub fn list_system_templates(&self) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.filter(stack_templates::generator_id.is_null())
.load::<StackTemplate>(conn)
}

pub

fn soft_delete(
&self,
template_id: Uuid,
) -> Result<usize, diesel::result::Error>

Soft deletes a stack template by setting its deleted_at timestamp.

Parameters:

Name Type Description
template_id Uuid The UUID of the template to soft delete.

Returns:

Returns a Result containing the number of affected rows (0 or 1).

Source
pub fn soft_delete(&self, template_id: Uuid) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::update(stack_templates::table.filter(stack_templates::id.eq(template_id)))
.set(stack_templates::deleted_at.eq(Utc::now()))
.execute(conn)
}

pub

fn hard_delete(
&self,
template_id: Uuid,
) -> Result<usize, diesel::result::Error>

Hard deletes a stack template from the database.

Parameters:

Name Type Description
template_id Uuid The UUID of the template to hard delete.

Returns:

Returns a Result containing the number of affected rows (0 or 1).

Source
pub fn hard_delete(&self, template_id: Uuid) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::delete(stack_templates::table.filter(stack_templates::id.eq(template_id)))
.execute(conn)
}

pub

fn filter_by_labels(
&self,
labels: Vec<String>,
filter_type: FilterType,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Filters templates by labels.

Parameters:

Name Type Description
labels Vec<String> A vector of label strings to filter by.
filter_type FilterType Specifies whether to use AND or OR logic for multiple labels.

Returns:

Returns a Result containing a Vec of matching StackTemplates.

Source
pub fn filter_by_labels(
&self,
labels: Vec<String>,
filter_type: FilterType,
) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
match filter_type {
FilterType::And => {
let mut query = stack_templates::table
.filter(stack_templates::deleted_at.is_null())
.into_boxed();
for label in &labels {
let subquery = template_labels::table
.filter(template_labels::template_id.eq(stack_templates::id))
.filter(template_labels::label.eq(label));
query = query.filter(diesel::dsl::exists(subquery));
}
query
.select(stack_templates::all_columns)
.distinct()
.load::<StackTemplate>(conn)
}
FilterType::Or => stack_templates::table
.inner_join(template_labels::table)
.filter(stack_templates::deleted_at.is_null())
.filter(template_labels::label.eq_any(labels))
.select(stack_templates::all_columns)
.distinct()
.load::<StackTemplate>(conn),
}
}

pub

fn filter_by_annotations(
&self,
annotations: Vec<(String, String)>,
filter_type: FilterType,
) -> Result<Vec<StackTemplate>, diesel::result::Error>

Filters templates by annotations.

Parameters:

Name Type Description
annotations Vec<(String, String)> A vector of (key, value) pairs to filter by.
filter_type FilterType Specifies whether to use AND or OR logic for multiple annotations.

Returns:

Returns a Result containing a Vec of matching StackTemplates.

Source
pub fn filter_by_annotations(
&self,
annotations: Vec<(String, String)>,
filter_type: FilterType,
) -> Result<Vec<StackTemplate>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
match filter_type {
FilterType::Or => {
let mut all_matching_templates = HashSet::new();
for (key, value) in annotations {
let matching_templates: Vec<StackTemplate> = stack_templates::table
.inner_join(template_annotations::table)
.filter(stack_templates::deleted_at.is_null())
.filter(template_annotations::key.eq(key))
.filter(template_annotations::value.eq(value))
.select(stack_templates::all_columns)
.load(conn)?;
all_matching_templates.extend(matching_templates);
}
Ok(all_matching_templates.into_iter().collect())
}
FilterType::And => {
if annotations.is_empty() {
return Ok(Vec::new());
}
let mut all_matching_templates: Option<HashSet<StackTemplate>> = None;
for (key, value) in annotations {
let matching_templates: HashSet<StackTemplate> = stack_templates::table
.inner_join(template_annotations::table)
.filter(stack_templates::deleted_at.is_null())
.filter(template_annotations::key.eq(key))
.filter(template_annotations::value.eq(value))
.select(stack_templates::all_columns)
.load(conn)?
.into_iter()
.collect();
all_matching_templates = match all_matching_templates {
Some(templates) => Some(
templates
.intersection(&matching_templates)
.cloned()
.collect(),
),
None => Some(matching_templates),
};
if let Some(ref templates) = all_matching_templates
&& templates.is_empty()
{
break;
}
}
Ok(all_matching_templates
.map_or_else(Vec::new, |templates| templates.into_iter().collect()))
}
}
}