use anyhow::Context;
use easy_macros::always_context;
use crate::{
Connection, Driver, Insert, Output, Table, macro_support::never_any, traits::DriverArguments,
};
use crate::macro_support;
use super::TestDriver;
#[derive(Debug, Table)]
#[sql(no_version)]
struct ExampleTable {
#[sql(primary_key)]
id: i64,
field0: String,
field1: String,
field2: i32,
field3: i64,
field4: i16,
}
#[allow(dead_code)]
#[derive(Debug, Output)]
#[sql(table = ExampleTable)]
struct ExampleOutput {
field1: String,
field2: i32,
field3: i64,
}
#[always_context]
#[no_context]
async fn _test_select() -> anyhow::Result<ExampleOutput> {
let mut fake_conn = never_any::<Connection<TestDriver>>();
let random_id = 42;
let result = {
use anyhow::Context;
use {crate::traits::ToConvert, sqlx::Arguments};
let mut args = macro_support::args_for_driver(&&mut fake_conn);
let mut query = "SELECT ".to_string();
let current_arg_n = 0;
let mut _easy_sql_d = macro_support::driver_identifier_delimiter(&&mut fake_conn);
let mut __easy_sql_parameter_placeholder =
macro_support::driver_parameter_placeholder(&&mut fake_conn);
macro_support::query_add_selected::<ExampleTable, ExampleOutput, _>(
&mut query,
&&mut fake_conn,
);
query.push_str(" FROM ");
query.push_str(<ExampleTable as Table<TestDriver>>::table_name());
query.push_str(&format!(
" WHERE {_easy_sql_d}id{_easy_sql_d} = {} AND {_easy_sql_d}field2{_easy_sql_d} > {}",
__easy_sql_parameter_placeholder(current_arg_n),
__easy_sql_parameter_placeholder(current_arg_n + 1)
));
args.add(&random_id).map_err(anyhow::Error::from_boxed)?;
let mut builder = sqlx::QueryBuilder::with_arguments(query, args);
let built_query = builder.build();
async fn execute<'a, T, O: Output<T, D>, D: Driver>(
exec: &mut impl crate::traits::EasyExecutor<D>,
query: sqlx::query::Query<'a, crate::traits::InternalDriver<D>, DriverArguments<'a, D>>,
) -> anyhow::Result<O> {
let raw_data = O::DataToConvert::get(exec.executor(), query).await?;
let result = O::convert(raw_data)?;
Ok(result)
}
execute::<ExampleTable, ExampleOutput, _>(&mut &mut fake_conn, built_query)
.await
.with_context(|| "Generated by macro")
}
.context("")?;
Ok(result)
}
#[always_context]
#[no_context]
async fn _test_insert() -> anyhow::Result<()> {
let mut fake_conn = never_any::<Connection<TestDriver>>();
let new_entry = ExampleTable {
id: 1,
field0: "test".to_string(),
field1: "example".to_string(),
field2: 123,
field3: 456,
field4: 7,
};
{
async {
async fn __easy_sql_perform<'a, T: Insert<'a, ExampleTable, TestDriver>>(
exec: &mut impl crate::EasyExecutor<TestDriver>,
to_insert: T,
) -> anyhow::Result<crate::traits::DriverQueryResult<TestDriver>> {
let mut args = DriverArguments::<TestDriver>::default();
let mut query = "INSERT INTO ".to_string();
let mut current_arg_n = 0;
let mut _easy_sql_d = TestDriver::identifier_delimiter();
query.push_str(<ExampleTable as Table<TestDriver>>::table_name());
query.push_str(" (");
let columns = <ExampleTable as Insert<ExampleTable, TestDriver>>::insert_columns();
for (i, col) in columns.iter().enumerate() {
if i > 0 {
query.push_str(", ");
}
query.push_str(&format!("{_easy_sql_d}{col}{_easy_sql_d}"));
}
query.push_str(") VALUES");
let (new_args, count) = to_insert
.insert_values(args)
.context("Failed to get insert values")?;
args = new_args;
for _ in 0..count {
query.push_str(" (");
for i in 0..columns.len() {
query.push_str(&TestDriver::parameter_placeholder(current_arg_n + i));
query.push(',');
}
current_arg_n += columns.len();
query.pop();
query.push_str("),");
}
query.pop();
let mut builder = sqlx::QueryBuilder::with_arguments(query, args);
let built_query = builder.build();
built_query
.execute(exec.executor())
.await
.context("Failed to execute insert query")
}
__easy_sql_perform(&mut &mut fake_conn, new_entry)
.await
.with_context(|| "Generated by macro")
}
}
.await
.context("")?;
Ok(())
}
#[always_context]
#[no_context]
async fn _test_update() -> anyhow::Result<()> {
let mut fake_conn = never_any::<Connection<TestDriver>>();
let data_update = ExampleTable {
id: 1,
field0: "updated_test".to_string(),
field1: "updated_example".to_string(),
field2: 456,
field3: 789,
field4: 10,
};
{
use sqlx::Arguments;
let mut args = DriverArguments::<TestDriver>::default();
let mut query = "UPDATE ".to_string();
let mut current_arg_n = 0;
let mut _easy_sql_d = TestDriver::identifier_delimiter();
query.push_str(<ExampleTable as Table<TestDriver>>::table_name());
query.push_str(" SET ");
args = crate::macro_support::query_update_data_selected_driver::<
ExampleTable,
TestDriver,
_,
>(&data_update, args, &mut query, &mut current_arg_n)?;
query.push_str(&format!(
" WHERE {_easy_sql_d}id{_easy_sql_d} = {}",
TestDriver::parameter_placeholder(current_arg_n)
));
args.add(&data_update.id)
.map_err(anyhow::Error::from_boxed)?;
async fn execute<'a>(
exec: impl sqlx::Executor<'a, Database = crate::traits::InternalDriver<TestDriver>>,
query: String,
args: DriverArguments<'a, TestDriver>,
) -> Result<crate::traits::DriverQueryResult<TestDriver>, sqlx::Error> {
let mut builder = sqlx::QueryBuilder::with_arguments(query, args);
let built_query = builder.build();
built_query.execute(exec).await
}
execute(&mut *fake_conn, query, args)
}
.await
.context("")?;
Ok(())
}
#[always_context]
#[no_context]
async fn _test_delete() -> anyhow::Result<()> {
let mut fake_conn = never_any::<Connection<TestDriver>>();
let delete_id = 1;
{
async {
use futures::FutureExt;
use sqlx::Arguments;
let mut args = DriverArguments::<TestDriver>::default();
let mut query = "DELETE FROM ".to_string();
let current_arg_n = 0;
let mut _easy_sql_d = TestDriver::identifier_delimiter();
query.push_str(<ExampleTable as Table<TestDriver>>::table_name());
query.push_str(&format!(
" WHERE {_easy_sql_d}id{_easy_sql_d} = {}",
TestDriver::parameter_placeholder(current_arg_n)
));
args.add(&delete_id).map_err(anyhow::Error::from_boxed)?;
async fn execute<'a>(
exec: &mut impl crate::EasyExecutor<TestDriver>,
query: String,
args: DriverArguments<'a, TestDriver>,
) -> Result<crate::traits::DriverQueryResult<TestDriver>, sqlx::Error> {
let mut builder = sqlx::QueryBuilder::with_arguments(query, args);
let built_query = builder.build();
built_query.execute(exec.executor()).await
}
execute(&mut &mut fake_conn, query, args)
.map(|r| r.with_context(|| "Generated by macro"))
.await
}
}
.await
.context("")?;
Ok(())
}