db_v1_queries_cost - OmniCloudOrg/OmniOrchestrator GitHub Wiki
Path: src/db/v1/queries/cost.rs
- async fn list_resource_types
- async fn count_resource_types
- async fn get_resource_type_by_id
- async fn create_resource_type
- async fn update_resource_type
- async fn delete_resource_type
- async fn list_cost_metrics
- async fn count_cost_metrics
- async fn create_cost_metric
- async fn get_cost_metric_by_id
- async fn delete_cost_metric
- async fn get_cost_metrics_by_dimension
- async fn get_app_cost_over_time
- async fn list_cost_budgets
- async fn count_cost_budgets
- async fn create_cost_budget
- async fn get_cost_budget_by_id
- async fn update_cost_budget
- async fn delete_cost_budget
- async fn list_cost_projections
- async fn create_cost_projection
- async fn get_cost_projection_by_id
- async fn delete_cost_projection
- async fn list_resource_pricing
- async fn create_resource_pricing
- async fn get_resource_pricing_by_id
- async fn update_resource_pricing
- async fn delete_resource_pricing
- async fn get_cost_allocation_tags
- async fn create_cost_allocation_tag
- async fn delete_cost_allocation_tag
pub async fn list_resource_types(pool: &Pool<MySql>, page: i64, per_page: i64) -> anyhow::Result<Vec<ResourceType>> {
println!("Attempting to fetch resource types from database...");
let result = sqlx::query_as::<_, ResourceType>(
r#"
SELECT * FROM resource_types
ORDER BY name ASC
LIMIT ? OFFSET ?
"#,
)
.bind(per_page)
.bind(page * per_page)
.fetch_all(pool)
.await;
match result {
Ok(types) => {
println!("Successfully fetched {} resource types", types.len());
Ok(types)
}
Err(e) => {
// ... function body
}
Retrieves a paginated list of resource types from the database.
-
pool
- Database connection pool for executing the query -
page
- Zero-based page number (e.g., 0 for first page, 1 for second page) -
per_page
- Number of records to fetch per page
-
Ok(Vec<ResourceType>)
- Successfully retrieved list of resource types -
Err(anyhow::Error)
- Failed to fetch resource types, with context
pub async fn count_resource_types(pool: &Pool<MySql>) -> anyhow::Result<i64> {
let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM resource_types")
.fetch_one(pool)
.await
.context("Failed to count resource types")?;
Ok(count)
}
/// Retrieves a specific resource type by its unique identifier.
pub async fn get_resource_type_by_id(pool: &Pool<MySql>, id: i32) -> anyhow::Result<ResourceType> {
let resource_type = sqlx::query_as::<_, ResourceType>("SELECT * FROM resource_types WHERE id = ?")
.bind(id)
.fetch_one(pool)
.await
.context("Failed to fetch resource type")?;
Ok(resource_type)
}
/// Creates a new resource type in the database.
// ... function definition continues
// ... function body
}
Counts the total number of resource types in the database.
pub async fn get_resource_type_by_id(pool: &Pool<MySql>, id: i32) -> anyhow::Result<ResourceType> {
let resource_type = sqlx::query_as::<_, ResourceType>("SELECT * FROM resource_types WHERE id = ?")
.bind(id)
.fetch_one(pool)
.await
.context("Failed to fetch resource type")?;
Ok(resource_type)
}
/// Creates a new resource type in the database.
pub async fn create_resource_type(
pool: &Pool<MySql>,
name: &str,
category: &str,
unit_of_measurement: &str,
description: Option<&str>
) -> anyhow::Result<ResourceType> {
let mut tx = pool.begin().await?;
let resource_type = sqlx::query_as::<_, ResourceType>(
// ... function definition continues
// ... function body
}
Retrieves a specific resource type by its unique identifier.
pub async fn create_resource_type(
pool: &Pool<MySql>,
name: &str,
category: &str,
unit_of_measurement: &str,
description: Option<&str>
) -> anyhow::Result<ResourceType> {
let mut tx = pool.begin().await?;
let resource_type = sqlx::query_as::<_, ResourceType>(
r#"INSERT INTO resource_types (
name, category, unit_of_measurement, description
) VALUES (?, ?, ?, ?)"#,
)
.bind(name)
.bind(category)
.bind(unit_of_measurement)
.bind(description)
.fetch_one(&mut *tx)
.await
.context("Failed to create resource type")?;
// ... function body
}
Creates a new resource type in the database.
pub async fn update_resource_type(
pool: &Pool<MySql>,
id: i32,
name: Option<&str>,
category: Option<&str>,
unit_of_measurement: Option<&str>,
description: Option<&str>
) -> anyhow::Result<ResourceType> {
// Define which fields are being updated
let update_fields = [
(name.is_some(), "name = ?"),
(category.is_some(), "category = ?"),
(unit_of_measurement.is_some(), "unit_of_measurement = ?"),
(description.is_some(), "description = ?"),
];
// Build update query with only the fields that have values
let field_clauses = update_fields
.iter()
.filter(|(has_value, _)| *has_value)
.map(|(_, field)| format!(", {}", field))
// ... function body
}
Updates an existing resource type in the database.
pub async fn delete_resource_type(pool: &Pool<MySql>, id: i32) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM resource_types WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete resource type")?;
tx.commit().await?;
Ok(())
}
/// Retrieves a paginated list of cost metrics from the database, with optional filtering.
///
/// # Arguments
///
/// * `pool` - Database connection pool for executing the query
/// * `page` - Zero-based page number (e.g., 0 for first page, 1 for second page)
/// * `per_page` - Number of records to fetch per page
/// * `resource_type_id` - Optional filter by resource type
// ... function definition continues
// ... function body
}
Deletes a resource type from the database.
pub async fn list_cost_metrics(
pool: &Pool<MySql>,
page: i64,
per_page: i64,
resource_type_id: Option<i32>,
provider_id: Option<i64>,
app_id: Option<i64>,
start_date: Option<DateTime<Utc>>,
end_date: Option<DateTime<Utc>>,
billing_period: Option<&str>
) -> anyhow::Result<Vec<CostMetricWithType>> {
println!("Attempting to fetch cost metrics from database with filters...");
// Start building the query with filters
let mut query = String::from(
r#"
SELECT
cm.*,
rt.name as resource_type_name,
rt.category as resource_type_category,
rt.unit_of_measurement
// ... function definition continues
// ... function body
}
Retrieves a paginated list of cost metrics from the database, with optional filtering.
-
pool
- Database connection pool for executing the query -
page
- Zero-based page number (e.g., 0 for first page, 1 for second page) -
per_page
- Number of records to fetch per page -
resource_type_id
- Optional filter by resource type -
provider_id
- Optional filter by provider -
app_id
- Optional filter by application -
start_date
- Optional filter for metrics after this date -
end_date
- Optional filter for metrics before this date -
billing_period
- Optional filter by billing period (e.g., "2025-05")
-
Ok(Vec<CostMetricWithType>)
- Successfully retrieved list of cost metrics with type information -
Err(anyhow::Error)
- Failed to fetch cost metrics, with context
pub async fn count_cost_metrics(
pool: &Pool<MySql>,
resource_type_id: Option<i32>,
provider_id: Option<i64>,
app_id: Option<i64>,
start_date: Option<DateTime<Utc>>,
end_date: Option<DateTime<Utc>>,
billing_period: Option<&str>
) -> anyhow::Result<i64> {
// Start building the query with filters
let mut query = String::from(
"SELECT COUNT(*) FROM cost_metrics WHERE 1=1"
);
if resource_type_id.is_some() {
query.push_str(" AND resource_type_id = ?");
}
if provider_id.is_some() {
query.push_str(" AND provider_id = ?");
}
// ... function definition continues
// ... function body
}
Counts the total number of cost metrics in the database with optional filtering.
pub async fn create_cost_metric(
pool: &Pool<MySql>,
resource_type_id: i32,
provider_id: Option<i64>,
region_id: Option<i64>,
app_id: Option<i64>,
worker_id: Option<i64>,
org_id: Option<i64>,
start_time: DateTime<Utc>,
end_time: DateTime<Utc>,
usage_quantity: f64,
unit_cost: f64,
currency: &str,
total_cost: f64,
discount_percentage: Option<f64>,
discount_reason: Option<&str>,
billing_period: Option<&str>
) -> anyhow::Result<CostMetric> {
let mut tx = pool.begin().await?;
let cost_metric = sqlx::query_as::<_, CostMetric>(
// ... function definition continues
// ... function body
}
Creates a new cost metric in the database.
pub async fn get_cost_metric_by_id(pool: &Pool<MySql>, id: i64) -> anyhow::Result<CostMetricWithType> {
let cost_metric = sqlx::query_as::<_, CostMetricWithType>(
r#"
SELECT
cm.id,
cm.resource_type_id,
cm.provider_id,
cm.region_id,
cm.app_id,
cm.worker_id,
cm.org_id,
cm.start_time,
cm.end_time,
cm.usage_quantity,
cm.unit_cost,
cm.currency,
cm.total_cost,
cm.discount_percentage,
cm.discount_reason,
cm.billing_period,
cm.created_at,
// ... function definition continues
// ... function body
}
Retrieves a specific cost metric by its unique identifier, with resource type information.
pub async fn delete_cost_metric(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM cost_metrics WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete cost metric")?;
tx.commit().await?;
Ok(())
}
/// Get aggregate cost metrics grouped by a specific dimension.
///
/// # Arguments
///
/// * `pool` - Database connection pool for executing the query
/// * `dimension` - Dimension to group by ('app', 'provider', 'resource_type', 'region', 'worker', 'org')
/// * `start_date` - Filter for metrics after this date
/// * `end_date` - Filter for metrics before this date
// ... function definition continues
// ... function body
}
Deletes a cost metric from the database.
pub async fn get_cost_metrics_by_dimension(
pool: &Pool<MySql>,
dimension: &str,
start_date: DateTime<Utc>,
end_date: DateTime<Utc>,
limit: i64
) -> anyhow::Result<Vec<(String, f64)>> {
// Validate and map the dimension to the appropriate SQL expression
let (group_field, join_clause) = match dimension {
"app" => ("apps.name", "LEFT JOIN apps ON cost_metrics.app_id = apps.id"),
"provider" => ("providers.name", "LEFT JOIN providers ON cost_metrics.provider_id = providers.id"),
"resource_type" => ("resource_types.name", "LEFT JOIN resource_types ON cost_metrics.resource_type_id = resource_types.id"),
"region" => ("regions.name", "LEFT JOIN regions ON cost_metrics.region_id = regions.id"),
"worker" => ("workers.name", "LEFT JOIN workers ON cost_metrics.worker_id = workers.id"),
"org" => ("orgs.name", "LEFT JOIN orgs ON cost_metrics.org_id = orgs.id"),
_ => return Err(anyhow::anyhow!("Invalid dimension: {}", dimension)),
};
let query = format!(
r#"
SELECT
// ... function definition continues
// ... function body
}
Get aggregate cost metrics grouped by a specific dimension.
-
pool
- Database connection pool for executing the query -
dimension
- Dimension to group by ('app', 'provider', 'resource_type', 'region', 'worker', 'org') -
start_date
- Filter for metrics after this date -
end_date
- Filter for metrics before this date -
limit
- Maximum number of results to return
-
Ok(Vec<(String, f64)>)
- Successfully retrieved aggregated costs by dimension -
Err(anyhow::Error)
- Failed to fetch cost metrics, with context
pub async fn get_app_cost_over_time(
pool: &Pool<MySql>,
app_id: i64,
interval: &str,
start_date: DateTime<Utc>,
end_date: DateTime<Utc>
) -> anyhow::Result<Vec<(DateTime<Utc>, f64)>> {
// Map the interval to the appropriate SQL date function
let date_function = match interval {
"day" => "DATE(start_time)",
"week" => "DATE(start_time - INTERVAL WEEKDAY(start_time) DAY)", // First day of week
"month" => "DATE_FORMAT(start_time, '%Y-%m-01')", // First day of month
_ => return Err(anyhow::anyhow!("Invalid interval: {}", interval)),
};
let query = format!(
r#"
SELECT
{} as time_bucket,
SUM(total_cost) as total_cost
FROM
// ... function definition continues
// ... function body
}
Retrieves cost metrics over time for a specific application.
-
pool
- Database connection pool for executing the query -
app_id
- ID of the application to analyze -
interval
- Time interval ('day', 'week', 'month') -
start_date
- Filter for metrics after this date -
end_date
- Filter for metrics before this date
-
Ok(Vec<(DateTime<Utc>, f64)>)
- Successfully retrieved costs over time -
Err(anyhow::Error)
- Failed to fetch cost metrics, with context
pub async fn list_cost_budgets(pool: &Pool<MySql>, page: i64, per_page: i64) -> anyhow::Result<Vec<CostBudget>> {
println!("Attempting to fetch cost budgets from database...");
let result = sqlx::query_as::<_, CostBudget>(
r#"
SELECT * FROM cost_budgets
ORDER BY created_at DESC
LIMIT ? OFFSET ?
"#,
)
.bind(per_page)
.bind(page * per_page)
.fetch_all(pool)
.await;
match result {
Ok(budgets) => {
println!("Successfully fetched {} cost budgets", budgets.len());
Ok(budgets)
}
Err(e) => {
// ... function body
}
Retrieves a paginated list of cost budgets from the database.
pub async fn count_cost_budgets(pool: &Pool<MySql>) -> anyhow::Result<i64> {
let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM cost_budgets")
.fetch_one(pool)
.await
.context("Failed to count cost budgets")?;
Ok(count)
}
/// Creates a new cost budget in the database.
pub async fn create_cost_budget(
pool: &Pool<MySql>,
org_id: i64,
app_id: Option<i64>,
budget_name: &str,
budget_amount: f64,
currency: &str,
budget_period: &str,
period_start: DateTime<Utc>,
period_end: DateTime<Utc>,
alert_threshold_percentage: f64,
// ... function definition continues
// ... function body
}
Counts the total number of cost budgets in the database.
pub async fn create_cost_budget(
pool: &Pool<MySql>,
org_id: i64,
app_id: Option<i64>,
budget_name: &str,
budget_amount: f64,
currency: &str,
budget_period: &str,
period_start: DateTime<Utc>,
period_end: DateTime<Utc>,
alert_threshold_percentage: f64,
alert_contacts: &str,
created_by: i64
) -> anyhow::Result<CostBudget> {
let mut tx = pool.begin().await?;
let cost_budget = sqlx::query_as::<_, CostBudget>(
r#"INSERT INTO cost_budgets (
org_id, app_id, budget_name, budget_amount, currency, budget_period,
period_start, period_end, alert_threshold_percentage, alert_contacts,
is_active, created_by
// ... function definition continues
// ... function body
}
Creates a new cost budget in the database.
pub async fn get_cost_budget_by_id(pool: &Pool<MySql>, id: i64) -> anyhow::Result<CostBudget> {
let cost_budget = sqlx::query_as::<_, CostBudget>("SELECT * FROM cost_budgets WHERE id = ?")
.bind(id)
.fetch_one(pool)
.await
.context("Failed to fetch cost budget")?;
Ok(cost_budget)
}
/// Updates an existing cost budget in the database.
pub async fn update_cost_budget(
pool: &Pool<MySql>,
id: i64,
budget_name: Option<&str>,
budget_amount: Option<f64>,
alert_threshold_percentage: Option<f64>,
alert_contacts: Option<&str>,
is_active: Option<bool>
) -> anyhow::Result<CostBudget> {
// Define which fields are being updated
// ... function definition continues
// ... function body
}
Retrieves a specific cost budget by its unique identifier.
pub async fn update_cost_budget(
pool: &Pool<MySql>,
id: i64,
budget_name: Option<&str>,
budget_amount: Option<f64>,
alert_threshold_percentage: Option<f64>,
alert_contacts: Option<&str>,
is_active: Option<bool>
) -> anyhow::Result<CostBudget> {
// Define which fields are being updated
let update_fields = [
(budget_name.is_some(), "budget_name = ?"),
(budget_amount.is_some(), "budget_amount = ?"),
(alert_threshold_percentage.is_some(), "alert_threshold_percentage = ?"),
(alert_contacts.is_some(), "alert_contacts = ?"),
(is_active.is_some(), "is_active = ?"),
];
// Build update query with only the fields that have values
let field_clauses = update_fields
.iter()
// ... function definition continues
// ... function body
}
Updates an existing cost budget in the database.
pub async fn delete_cost_budget(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM cost_budgets WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete cost budget")?;
tx.commit().await?;
Ok(())
}
/// Retrieves a paginated list of cost projections from the database.
pub async fn list_cost_projections(pool: &Pool<MySql>, page: i64, per_page: i64) -> anyhow::Result<Vec<CostProjection>> {
println!("Attempting to fetch cost projections from database...");
let result = sqlx::query_as::<_, CostProjection>(
r#"
SELECT * FROM cost_projections
ORDER BY created_at DESC
// ... function definition continues
// ... function body
}
Deletes a cost budget from the database.
pub async fn list_cost_projections(pool: &Pool<MySql>, page: i64, per_page: i64) -> anyhow::Result<Vec<CostProjection>> {
println!("Attempting to fetch cost projections from database...");
let result = sqlx::query_as::<_, CostProjection>(
r#"
SELECT * FROM cost_projections
ORDER BY created_at DESC
LIMIT ? OFFSET ?
"#,
)
.bind(per_page)
.bind(page * per_page)
.fetch_all(pool)
.await;
match result {
Ok(projections) => {
println!("Successfully fetched {} cost projections", projections.len());
Ok(projections)
}
Err(e) => {
// ... function body
}
Retrieves a paginated list of cost projections from the database.
pub async fn create_cost_projection(
pool: &Pool<MySql>,
org_id: i64,
app_id: Option<i64>,
projection_period: &str,
start_date: DateTime<Utc>,
end_date: DateTime<Utc>,
projected_cost: f64,
currency: &str,
projection_model: &str,
confidence_level: Option<f64>,
metadata: Option<&str>
) -> anyhow::Result<CostProjection> {
let mut tx = pool.begin().await?;
let cost_projection = sqlx::query_as::<_, CostProjection>(
r#"INSERT INTO cost_projections (
org_id, app_id, projection_period, start_date, end_date,
projected_cost, currency, projection_model, confidence_level, metadata
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"#,
)
// ... function definition continues
// ... function body
}
Creates a new cost projection in the database.
pub async fn get_cost_projection_by_id(pool: &Pool<MySql>, id: i64) -> anyhow::Result<CostProjection> {
let cost_projection = sqlx::query_as::<_, CostProjection>("SELECT * FROM cost_projections WHERE id = ?")
.bind(id)
.fetch_one(pool)
.await
.context("Failed to fetch cost projection")?;
Ok(cost_projection)
}
/// Deletes a cost projection from the database.
pub async fn delete_cost_projection(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM cost_projections WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete cost projection")?;
tx.commit().await?;
// ... function body
}
Retrieves a specific cost projection by its unique identifier.
pub async fn delete_cost_projection(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM cost_projections WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete cost projection")?;
tx.commit().await?;
Ok(())
}
/// Retrieves a paginated list of resource pricing entries from the database.
pub async fn list_resource_pricing(
pool: &Pool<MySql>,
page: i64,
per_page: i64,
resource_type_id: Option<i32>,
provider_id: Option<i64>,
region_id: Option<i64>,
// ... function definition continues
// ... function body
}
Deletes a cost projection from the database.
pub async fn list_resource_pricing(
pool: &Pool<MySql>,
page: i64,
per_page: i64,
resource_type_id: Option<i32>,
provider_id: Option<i64>,
region_id: Option<i64>,
pricing_model: Option<&str>,
tier_name: Option<&str>
) -> anyhow::Result<Vec<ResourcePricing>> {
println!("Attempting to fetch resource pricing from database with filters...");
// Start building the query with filters
let mut query = String::from(
"SELECT * FROM resource_pricing WHERE 1=1"
);
if resource_type_id.is_some() {
query.push_str(" AND resource_type_id = ?");
}
// ... function definition continues
// ... function body
}
Retrieves a paginated list of resource pricing entries from the database.
pub async fn create_resource_pricing(
pool: &Pool<MySql>,
resource_type_id: i32,
provider_id: i64,
region_id: Option<i64>,
tier_name: &str,
unit_price: f64,
currency: &str,
effective_from: DateTime<Utc>,
effective_to: Option<DateTime<Utc>>,
pricing_model: &str,
commitment_period: Option<&str>,
volume_discount_tiers: Option<&str>
) -> anyhow::Result<ResourcePricing> {
let mut tx = pool.begin().await?;
let resource_pricing = sqlx::query_as::<_, ResourcePricing>(
r#"INSERT INTO resource_pricing (
resource_type_id, provider_id, region_id, tier_name, unit_price,
currency, effective_from, effective_to, pricing_model,
commitment_period, volume_discount_tiers
// ... function definition continues
// ... function body
}
Creates a new resource pricing entry in the database.
pub async fn get_resource_pricing_by_id(pool: &Pool<MySql>, id: i64) -> anyhow::Result<ResourcePricing> {
let resource_pricing = sqlx::query_as::<_, ResourcePricing>("SELECT * FROM resource_pricing WHERE id = ?")
.bind(id)
.fetch_one(pool)
.await
.context("Failed to fetch resource pricing")?;
Ok(resource_pricing)
}
/// Updates an existing resource pricing entry in the database.
pub async fn update_resource_pricing(
pool: &Pool<MySql>,
id: i64,
unit_price: Option<f64>,
effective_to: Option<DateTime<Utc>>,
volume_discount_tiers: Option<&str>
) -> anyhow::Result<ResourcePricing> {
// Define which fields are being updated
let update_fields = [
(unit_price.is_some(), "unit_price = ?"),
// ... function definition continues
// ... function body
}
Retrieves a specific resource pricing entry by its unique identifier.
pub async fn update_resource_pricing(
pool: &Pool<MySql>,
id: i64,
unit_price: Option<f64>,
effective_to: Option<DateTime<Utc>>,
volume_discount_tiers: Option<&str>
) -> anyhow::Result<ResourcePricing> {
// Define which fields are being updated
let update_fields = [
(unit_price.is_some(), "unit_price = ?"),
(effective_to.is_some(), "effective_to = ?"),
(volume_discount_tiers.is_some(), "volume_discount_tiers = ?"),
];
// Build update query with only the fields that have values
let field_clauses = update_fields
.iter()
.filter(|(has_value, _)| *has_value)
.map(|(_, field)| format!(", {}", field))
.collect::<String>();
// ... function definition continues
// ... function body
}
Updates an existing resource pricing entry in the database.
pub async fn delete_resource_pricing(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM resource_pricing WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete resource pricing")?;
tx.commit().await?;
Ok(())
}
/// Retrieves a list of cost allocation tags for a specific resource.
pub async fn get_cost_allocation_tags(
pool: &Pool<MySql>,
resource_id: i64,
resource_type: &str
) -> anyhow::Result<Vec<CostAllocationTag>> {
let tags = sqlx::query_as::<_, CostAllocationTag>(
"SELECT * FROM cost_allocation_tags WHERE resource_id = ? AND resource_type = ?"
// ... function definition continues
// ... function body
}
Deletes a resource pricing entry from the database.
pub async fn get_cost_allocation_tags(
pool: &Pool<MySql>,
resource_id: i64,
resource_type: &str
) -> anyhow::Result<Vec<CostAllocationTag>> {
let tags = sqlx::query_as::<_, CostAllocationTag>(
"SELECT * FROM cost_allocation_tags WHERE resource_id = ? AND resource_type = ?"
)
.bind(resource_id)
.bind(resource_type)
.fetch_all(pool)
.await
.context("Failed to fetch cost allocation tags")?;
Ok(tags)
}
/// Creates a new cost allocation tag in the database.
pub async fn create_cost_allocation_tag(
pool: &Pool<MySql>,
tag_key: &str,
// ... function definition continues
// ... function body
}
Retrieves a list of cost allocation tags for a specific resource.
pub async fn create_cost_allocation_tag(
pool: &Pool<MySql>,
tag_key: &str,
tag_value: &str,
resource_id: i64,
resource_type: &str
) -> anyhow::Result<CostAllocationTag> {
let mut tx = pool.begin().await?;
let tag = sqlx::query_as::<_, CostAllocationTag>(
r#"INSERT INTO cost_allocation_tags (
tag_key, tag_value, resource_id, resource_type
) VALUES (?, ?, ?, ?)"#,
)
.bind(tag_key)
.bind(tag_value)
.bind(resource_id)
.bind(resource_type)
.fetch_one(&mut *tx)
.await
.context("Failed to create cost allocation tag")?;
// ... function body
}
Creates a new cost allocation tag in the database.
pub async fn delete_cost_allocation_tag(pool: &Pool<MySql>, id: i64) -> anyhow::Result<()> {
let mut tx = pool.begin().await?;
sqlx::query("DELETE FROM cost_allocation_tags WHERE id = ?")
.bind(id)
.execute(&mut *tx)
.await
.context("Failed to delete cost allocation tag")?;
tx.commit().await?;
Ok(())
// ... function body
}
Deletes a cost allocation tag from the database.