use super::HasOne;
use crate::relation::has_many::default_foreign_key;
pub fn php_has_one(
parent_class: &str,
child_table: &str,
foreign_key: Option<&str>,
child_pk: Option<&str>,
) -> HasOne {
HasOne {
foreign_key: foreign_key
.map(String::from)
.unwrap_or_else(|| default_foreign_key(parent_class)),
child_model: child_table.to_string(),
child_pk: child_pk
.map(String::from)
.unwrap_or_else(|| "id".to_string()),
}
}
pub fn has_one_sql(child_table: &str, foreign_key: &str, parent_pk_value: &str) -> String {
format!(
"SELECT * FROM {} WHERE {} = {}",
child_table, foreign_key, parent_pk_value
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_php_has_one_default_foreign_key() {
let rel = php_has_one("User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_eq!(rel.child_model, "profiles");
assert_eq!(rel.child_pk, "id");
}
#[test]
fn test_php_has_one_explicit_foreign_key() {
let rel = php_has_one("User", "profiles", Some("uid"), None);
assert_eq!(rel.foreign_key, "uid");
assert_eq!(rel.child_model, "profiles");
assert_eq!(rel.child_pk, "id");
}
#[test]
fn test_php_has_one_explicit_child_pk() {
let rel = php_has_one("User", "profiles", Some("uid"), Some("pid"));
assert_eq!(rel.foreign_key, "uid");
assert_eq!(rel.child_model, "profiles");
assert_eq!(rel.child_pk, "pid");
}
#[test]
fn test_php_has_one_multi_word_parent() {
let rel = php_has_one("OrderItem", "order_item_details", None, None);
assert_eq!(rel.foreign_key, "order_item_id");
assert_eq!(rel.child_model, "order_item_details");
}
#[test]
fn test_php_has_one_with_namespace_parent() {
let rel = php_has_one("app\\model\\User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
}
#[test]
fn test_has_one_sql_numeric_pk() {
let sql = has_one_sql("profiles", "user_id", "1");
assert_eq!(sql, "SELECT * FROM profiles WHERE user_id = 1");
}
#[test]
fn test_has_one_sql_string_pk() {
let sql = has_one_sql("profiles", "user_id", "'abc-123'");
assert_eq!(sql, "SELECT * FROM profiles WHERE user_id = 'abc-123'");
}
#[test]
fn test_has_one_sql_custom_foreign_key() {
let sql = has_one_sql("profiles", "uid", "1");
assert_eq!(sql, "SELECT * FROM profiles WHERE uid = 1");
}
#[test]
fn test_has_one_sql_multi_word_table() {
let sql = has_one_sql("order_item_details", "order_item_id", "1");
assert_eq!(
sql,
"SELECT * FROM order_item_details WHERE order_item_id = 1"
);
}
#[test]
fn test_has_one_sql_aligns_sz_orm_core_pattern() {
let sql = has_one_sql("profiles", "user_id", "1");
assert!(sql.starts_with("SELECT * FROM profiles WHERE user_id = "));
}
#[test]
fn test_r5_php_has_one_default_foreign_key_convention() {
let rel = php_has_one("User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_eq!(
rel.foreign_key,
crate::relation::has_many::default_foreign_key("User")
);
}
#[test]
fn test_r5_php_has_one_explicit_fk_overrides_default() {
let rel = php_has_one("User", "profiles", Some("uid"), None);
assert_eq!(rel.foreign_key, "uid");
assert_ne!(
rel.foreign_key,
crate::relation::has_many::default_foreign_key("User")
);
}
#[test]
fn test_r5_php_has_one_default_local_key_is_id() {
let rel = php_has_one("User", "profiles", None, None);
assert_eq!(rel.child_pk, "id");
}
#[test]
fn test_r5_php_has_one_sql_pattern_matches_think_orm() {
let sql = has_one_sql("profiles", "user_id", "1");
assert_eq!(sql, "SELECT * FROM profiles WHERE user_id = 1");
}
#[test]
fn test_r5_php_has_one_returns_single_model() {
let rel = php_has_one("User", "profiles", None, None);
assert!(!rel.child_model.is_empty());
assert!(!rel.foreign_key.is_empty());
assert!(!rel.child_pk.is_empty());
}
#[test]
fn test_r5_php_has_one_namespace_handling() {
let rel = php_has_one("app\\model\\User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
let rel = php_has_one("app\\model\\OrderItem", "order_item_details", None, None);
assert_eq!(rel.foreign_key, "order_item_id");
let rel = php_has_one("App\\Model\\User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
}
#[test]
fn test_r5_php_has_one_same_algorithm_as_has_many() {
let has_one_rel = php_has_one("User", "profiles", None, None);
let has_many_rel = crate::relation::has_many::php_has_many("User", "orders", None, None);
assert_eq!(has_one_rel.foreign_key, has_many_rel.foreign_key);
assert_eq!(has_one_rel.foreign_key, "user_id");
}
#[test]
fn test_r5_php_has_one_delegates_to_sz_orm_core() {
let rel = php_has_one("User", "profiles", None, None);
let _: &HasOne = &rel;
let relation = sz_orm_core::Relation::HasOne(rel.clone());
assert!(matches!(relation, sz_orm_core::Relation::HasOne(_)));
}
#[test]
fn test_integration_user_has_one_profile() {
let rel = php_has_one("User", "profiles", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_eq!(rel.child_model, "profiles");
assert_eq!(rel.child_pk, "id");
let sql = has_one_sql(&rel.child_model, &rel.foreign_key, "1");
assert_eq!(sql, "SELECT * FROM profiles WHERE user_id = 1");
}
#[test]
fn test_integration_customer_has_one_account() {
let rel = php_has_one("Customer", "accounts", Some("customer_id"), None);
assert_eq!(rel.foreign_key, "customer_id");
assert_eq!(rel.child_model, "accounts");
let sql = has_one_sql(&rel.child_model, &rel.foreign_key, "100");
assert_eq!(sql, "SELECT * FROM accounts WHERE customer_id = 100");
}
#[test]
fn test_integration_order_has_one_shipping() {
let rel = php_has_one("Order", "shippings", None, None);
assert_eq!(rel.foreign_key, "order_id");
assert_eq!(rel.child_model, "shippings");
let sql = has_one_sql(&rel.child_model, &rel.foreign_key, "50");
assert_eq!(sql, "SELECT * FROM shippings WHERE order_id = 50");
}
#[test]
fn test_integration_order_item_has_one_detail() {
let rel = php_has_one("OrderItem", "order_item_details", None, None);
assert_eq!(rel.foreign_key, "order_item_id");
assert_eq!(rel.child_model, "order_item_details");
let sql = has_one_sql(&rel.child_model, &rel.foreign_key, "30");
assert_eq!(
sql,
"SELECT * FROM order_item_details WHERE order_item_id = 30"
);
}
}