use lazy_static::lazy_static;
#[rustfmt::skip]
lazy_static! {
pub static ref IQL_TEMPLATE: &'static str = r#"
use lazy_static::lazy_static;
use anyhow::Context as _;
use serde::{Deserialize, Serialize};
use sqlx::{MySql, Pool, QueryBuilder, Row};
use sqlx::mysql::MySqlRow;
lazy_static! {
#[rustfmt::skip]
pub static ref SELECT_STATMENT: &'static str = "select {{#each fields}}{{this.db_field_name}}{{#if (not @last) }}, {{/if}}{{/each}} from {{ table_name }}";
}
// use crate::core::error2::Error;
use crate::core::error2::Result;
#[rustfmt::skip]
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct {{ struct_name }} {
{{#each fields}}
{{# if this.nullable }}
#[serde(skip_serializing_if = "Option::is_none")]
{{else if (eq this.rust_type "String") }}
#[serde(skip_serializing_if = "String::is_empty")]
{{/if}}
pub {{this.name}}: {{# if this.nullable }}Option<{{this.rust_type}}>{{else}}{{this.rust_type}}{{/if}},
{{/each}}
}
#[rustfmt::skip]
#[allow(dead_code)]
impl {{ struct_name }} {
pub fn new() -> Self {
Self {
..Default::default()
}
}
pub async fn select_by_primary_key(pool: &Pool<MySql>, {{ pk_rs_name }}: {{{ pk_rs_type }}}) -> Result<Option<MySqlRow>> {
#[rustfmt::skip]
let statment: &str = *SELECT_STATMENT;
let mut query_builder: sqlx::QueryBuilder<sqlx::MySql> = sqlx::QueryBuilder::new(statment);
query_builder.push(" where {{ pk_db_name }} = ");
query_builder.push_bind({{ pk_rs_name }});
let row = query_builder
.build()
.fetch_optional(pool)
.await
.context("select_by_primary_key: Failed to perform a query to retrieve a otpcode.")?;
Ok(row)
}
pub async fn insert(pool: &Pool<MySql>, record: &{{ struct_name }}) -> Result<u64> {
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
"INSERT INTO {{ table_name }} ({{#each fields}}{{this.db_field_name}}{{#if (not @last) }}, {{/if}}{{/each}}) ",
);
query_builder.push_values([record].iter(), |mut b, record| {
{{#each fields}}
b.push_bind(record.{{this.name}}.to_owned());
{{/each}}
});
let mut transaction = pool.begin().await.map_err(|e| {
log::error!("insert-failed: error={:?}", e);
anyhow::anyhow!(e)
})?;
let last_insert_id = query_builder
.build()
// .execute(pool)
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!(e))?
.last_insert_id();
// if commit or rollback have not been called before the Transaction object goes out of scope (i.e. Drop is invoked),
// a rollback command is queued to be executed as soon as an opportunity arises.
transaction.commit().await.map_err(|e| {
log::error!("insert-failed: error={:?}", e);
anyhow::anyhow!(e)
})?;
Ok(last_insert_id)
}
pub async fn insert_bulk(pool: &Pool<MySql>, data: Vec<{{ struct_name }}>) -> Result<u64> {
let mut insert_result_int = 0;
for chunk in data.chunks(5000) {
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new(
"INSERT INTO {{ table_name }} ({{#each fields}}{{this.db_field_name}}{{#if (not @last) }}, {{/if}}{{/each}}) ",
);
query_builder.push_values(chunk.iter().take(5000 / {{field_count}}), |mut b, record| {
{{#each fields}}
b.push_bind(record.{{this.name}}.to_owned());
{{/each}}
});
insert_result_int += query_builder
.build()
.execute(pool)
.await
.map_err(|e| anyhow::anyhow!(e))?
.rows_affected();
}
Ok(insert_result_int)
}
pub async fn update_by_primary_key(
pool: &Pool<MySql>,
{{ pk_rs_name }}: {{{ pk_rs_type }}},
data: &{{ struct_name }},
) -> Result<bool> {
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new("update {{ table_name }} ");
{{#each fields}}
query_builder.push("{{#if @first }}set {{else if (not @first)}}, {{/if}}{{this.db_field_name}} = ");
{{#if this.nullable}}
if let Some(_{{this.name}}) = &data.{{this.name}} {
{{#if (eq this.rust_type "String")}}
if _{{this.name}}.trim() != "" {
query_builder.push_bind(_{{this.name}}.trim());
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{else}}
query_builder.push_bind(_{{this.name}});
{{/if}}
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{else}}
if data.{{this.name}}{{#if (eq this.rust_type "String")}}.trim(){{/if}} != "" {
{{#if (eq this.rust_type "String")}}
query_builder.push_bind(data.{{this.name}}.trim());
{{else}}
query_builder.push_bind(data.{{this.name}});
{{/if}}
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{/if}}
{{/each}}
query_builder.push(" where {{ pk_db_name }} = ");
query_builder.push_bind({{ pk_rs_name }});
let update_result_int = query_builder
.build()
.execute(pool)
.await
.map_err(|e| anyhow::anyhow!(e))?
.rows_affected();
Ok(update_result_int > 0)
}
pub async fn update_by_primary_key_selective(
pool: &Pool<MySql>,
{{ pk_rs_name }}: {{{ pk_rs_type }}},
data: &{{ struct_name }},
) -> Result<bool> {
let mut query_builder: QueryBuilder<MySql> = QueryBuilder::new("update {{ table_name }}");
{{#each fields}}
query_builder.push("{{#if @first }}set {{else if (not @first)}}, {{/if}}{{this.db_field_name}} = ");
{{#if this.nullable}}
if let Some(_{{this.name}}) = &data.{{this.name}} {
{{#if (eq this.rust_type "String")}}
if _{{this.name}}.trim() != "" {
query_builder.push_bind(_{{this.name}}.trim());
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{else}}
query_builder.push_bind(_{{this.name}});
{{/if}}
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{else}}
if data.{{this.name}}{{#if (eq this.rust_type "String")}}.trim(){{/if}} != "" {
{{#if (eq this.rust_type "String")}}
query_builder.push_bind(data.{{this.name}}.trim());
{{else}}
query_builder.push_bind(data.{{this.name}});
{{/if}}
} else {
query_builder.push_bind(None::<{{this.rust_type}}>);
}
{{/if}}
{{/each}}
query_builder.push(" where {{ pk_db_name }} = ");
query_builder.push_bind({{ pk_rs_name }});
let update_result_int = query_builder
.build()
.execute(pool)
.await
.map_err(|e| anyhow::anyhow!(e))?
.rows_affected();
Ok(update_result_int > 0)
}
pub fn from_row(row: sqlx::mysql::MySqlRow) -> Result<{{ struct_name }}> {
Ok({{ struct_name }} {
{{#each fields}}
{{this.name}}: row.get({{@index}}),
{{/each}}
})
}
}
"#;
}