Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/ts_generator/sql_parser/translate_delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ use crate::core::connection::DBConn;
use crate::ts_generator::errors::TsGeneratorError;
use crate::ts_generator::sql_parser::expressions::translate_expr::translate_expr;
use crate::ts_generator::types::ts_query::TsQuery;
use sqlparser::ast::Expr;
use sqlparser::ast::{Expr, TableWithJoins};

pub async fn translate_delete(
ts_query: &mut TsQuery,
where_conditions: &Expr, // WHERE conditions of the delete statement
table_name: &str,
table_with_joins: &Option<Vec<TableWithJoins>>, // Includes FROM and USING tables
db_conn: &DBConn,
) -> Result<(), TsGeneratorError> {
translate_expr(
where_conditions,
&Some(table_name),
&None,
table_with_joins,
None,
ts_query,
db_conn,
Expand Down
10 changes: 9 additions & 1 deletion src/ts_generator/sql_parser/translate_stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,15 @@ pub async fn translate_stmt(
let table_name = get_default_table(from);
let table_name_str = table_name.as_str();
let selection = delete.selection.to_owned().unwrap();
translate_delete(ts_query, &selection, table_name_str, db_conn).await?;

// Build a combined Vec<TableWithJoins> that includes both FROM and USING tables
let mut all_tables = from.to_vec();
if let Some(using_tables) = &delete.using {
all_tables.extend(using_tables.clone());
}
let table_with_joins = if all_tables.is_empty() { None } else { Some(all_tables) };

translate_delete(ts_query, &selection, table_name_str, &table_with_joins, db_conn).await?;

// Handle RETURNING clause if present
if delete.returning.is_some() {
Expand Down
138 changes: 137 additions & 1 deletion tests/mysql_delete_query_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,148 @@ r#"
export type SomeDeleteQueryParams = [number, number];

export interface ISomeDeleteQueryResult {

}

export interface ISomeDeleteQueryQuery {
params: SomeDeleteQueryParams;
result: ISomeDeleteQueryResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_with_join_using_aliases, TestConfig::new("mysql", true, None, None),

//// TS query ////
r#"
const deleteInventory = sql`
DELETE inv FROM inventory inv
INNER JOIN characters c ON inv.character_id = c.id
WHERE c.id = ?
AND inv.id = ?;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteInventoryParams = [number, number];

export interface IDeleteInventoryResult {

}

export interface IDeleteInventoryQuery {
params: DeleteInventoryParams;
result: IDeleteInventoryResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_with_multiple_joins, TestConfig::new("mysql", true, None, None),

//// TS query ////
r#"
const deleteItems = sql`
DELETE i FROM items i
INNER JOIN inventory inv ON i.inventory_id = inv.id
INNER JOIN characters c ON inv.character_id = c.id
WHERE c.id = ?
AND i.rarity = ?;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteItemsParams = [number, string | null];

export interface IDeleteItemsResult {

}

export interface IDeleteItemsQuery {
params: DeleteItemsParams;
result: IDeleteItemsResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_with_left_join, TestConfig::new("mysql", true, None, None),

//// TS query ////
r#"
const deleteByCharacter = sql`
DELETE inv FROM inventory inv
LEFT JOIN characters c ON inv.character_id = c.id
WHERE c.id = ?
AND inv.quantity = 0;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteByCharacterParams = [number];

export interface IDeleteByCharacterResult {

}

export interface IDeleteByCharacterQuery {
params: DeleteByCharacterParams;
result: IDeleteByCharacterResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_with_comparison_and_join, TestConfig::new("mysql", true, None, None),

//// TS query ////
r#"
const deleteByQuantity = sql`
DELETE inv FROM inventory inv
INNER JOIN items i ON i.inventory_id = inv.id
WHERE i.rarity = ?
AND inv.quantity < ?;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteByQuantityParams = [string | null, number | null];

export interface IDeleteByQuantityResult {

}

export interface IDeleteByQuantityQuery {
params: DeleteByQuantityParams;
result: IDeleteByQuantityResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_with_or_conditions_and_join, TestConfig::new("mysql", true, None, None),

//// TS query ////
r#"
const deleteConditional = sql`
DELETE inv FROM inventory inv
INNER JOIN characters c ON inv.character_id = c.id
WHERE (c.id = ? OR c.name = ?)
AND inv.quantity = 0;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteConditionalParams = [number, string];

export interface IDeleteConditionalResult {

}

export interface IDeleteConditionalQuery {
params: DeleteConditionalParams;
result: IDeleteConditionalResult;
}
"#);
}
142 changes: 141 additions & 1 deletion tests/postgres_delete_query_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,152 @@ r#"
export type SomeDeleteQueryParams = [number, number];

export interface ISomeDeleteQueryResult {

}

export interface ISomeDeleteQueryQuery {
params: SomeDeleteQueryParams;
result: ISomeDeleteQueryResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_using_with_aliases, TestConfig::new("postgres", true, None, None),

//// TS query ////
r#"
const deleteInventory = sql`
DELETE FROM inventory inv
USING characters c
WHERE inv.character_id = c.id
AND c.id = $1
AND inv.id = $2;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteInventoryParams = [number, number];

export interface IDeleteInventoryResult {

}

export interface IDeleteInventoryQuery {
params: DeleteInventoryParams;
result: IDeleteInventoryResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_using_with_multiple_tables, TestConfig::new("postgres", true, None, None),

//// TS query ////
r#"
const deleteItems = sql`
DELETE FROM items i
USING inventory inv, characters c
WHERE i.inventory_id = inv.id
AND inv.character_id = c.id
AND c.id = $1
AND i.rarity = $2;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteItemsParams = [number, string | null];

export interface IDeleteItemsResult {

}

export interface IDeleteItemsQuery {
params: DeleteItemsParams;
result: IDeleteItemsResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_using_with_comparison, TestConfig::new("postgres", true, None, None),

//// TS query ////
r#"
const deleteOldInventory = sql`
DELETE FROM inventory inv
USING characters c
WHERE inv.character_id = c.id
AND c.id = $1
AND inv.quantity > $2;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteOldInventoryParams = [number, number | null];

export interface IDeleteOldInventoryResult {

}

export interface IDeleteOldInventoryQuery {
params: DeleteOldInventoryParams;
result: IDeleteOldInventoryResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_using_with_in_clause, TestConfig::new("postgres", true, None, None),

//// TS query ////
r#"
const deleteByRarity = sql`
DELETE FROM inventory inv
USING items i
WHERE i.inventory_id = inv.id
AND i.rarity = $1;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteByRarityParams = [string | null];

export interface IDeleteByRarityResult {

}

export interface IDeleteByRarityQuery {
params: DeleteByRarityParams;
result: IDeleteByRarityResult;
}
"#);

#[rustfmt::skip]
run_test!(should_handle_delete_using_with_or_conditions, TestConfig::new("postgres", true, None, None),

//// TS query ////
r#"
const deleteConditional = sql`
DELETE FROM inventory inv
USING characters c
WHERE inv.character_id = c.id
AND (c.id = $1 OR c.name = $2)
AND inv.quantity = 0;
`
"#,

//// Generated TS interfaces ////
r#"
export type DeleteConditionalParams = [number, string];

export interface IDeleteConditionalResult {

}

export interface IDeleteConditionalQuery {
params: DeleteConditionalParams;
result: IDeleteConditionalResult;
}
"#);
}
44 changes: 44 additions & 0 deletions tests/sample/sample.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export type SampleSelectQueryParams = [number];

export interface ISampleSelectQueryResult {
name: string;
some_id: number;
}

export interface ISampleSelectQueryQuery {
params: SampleSelectQueryParams;
result: ISampleSelectQueryResult;
}

export type SampleInsertQueryParams = [string];

export interface ISampleInsertQueryResult {

}

export interface ISampleInsertQueryQuery {
params: SampleInsertQueryParams;
result: ISampleInsertQueryResult;
}

export type SampleUpdateQueryParams = [string, number];

export interface ISampleUpdateQueryResult {

}

export interface ISampleUpdateQueryQuery {
params: SampleUpdateQueryParams;
result: ISampleUpdateQueryResult;
}

export type SampleDeleteQueryParams = [number];

export interface ISampleDeleteQueryResult {

}

export interface ISampleDeleteQueryQuery {
params: SampleDeleteQueryParams;
result: ISampleDeleteQueryResult;
}
Loading