1use crate::qb::{bind::BindValue, condition::Condition};
2use std::marker::PhantomData;
3
4#[derive(Debug)]
21pub struct Column<T> {
22 pub name: &'static str,
24
25 pub aliased_name: &'static str,
28
29 pub table_alias: &'static str,
31
32 pub _marker: PhantomData<T>,
34}
35impl<T> AsRef<str> for Column<T> {
36 fn as_ref(&self) -> &str {
37 self.name
38 }
39}
40
41impl<T> Copy for Column<T> {}
42impl<T> Clone for Column<T> {
43 fn clone(&self) -> Self {
44 *self
45 }
46}
47
48impl<T> Column<T>
49where
50 T: BindValue + Clone,
51{
52 fn qualified_name(&self) -> String {
54 format!("{}.{}", self.table_alias, self.name)
55 }
56
57 pub fn eq(self, val: T) -> Condition {
59 Condition::new(format!("{} = ?", self.qualified_name()), val)
60 }
61
62 pub fn ne(self, val: T) -> Condition {
64 Condition::new(format!("{} <> ?", self.qualified_name()), val)
65 }
66
67 pub fn gt(self, val: T) -> Condition {
69 Condition::new(format!("{} > ?", self.qualified_name()), val)
70 }
71
72 pub fn ge(self, val: T) -> Condition {
74 Condition::new(format!("{} >= ?", self.qualified_name()), val)
75 }
76
77 pub fn lt(self, val: T) -> Condition {
79 Condition::new(format!("{} < ?", self.qualified_name()), val)
80 }
81
82 pub fn le(self, val: T) -> Condition {
84 Condition::new(format!("{} <= ?", self.qualified_name()), val)
85 }
86
87 pub fn like(self, val: T) -> Condition {
89 Condition::new(format!("{} LIKE ?", self.qualified_name()), val)
90 }
91
92 pub fn in_(self, vals: Vec<T>) -> Condition {
98 if vals.is_empty() {
99 panic!(
100 "Cannot create IN condition with empty value list. At least one value must be specified."
101 );
102 }
103 let placeholders: Vec<String> = (0..vals.len()).map(|_| "?".to_string()).collect();
104 let sql = format!("{} IN ({})", self.qualified_name(), placeholders.join(", "));
105 Condition::multi(sql, vals)
106 }
107
108 pub fn not_in(self, vals: Vec<T>) -> Condition {
112 if vals.is_empty() {
113 panic!(
114 "Cannot create NOT IN condition with empty value list. At least one value must be specified."
115 );
116 }
117 let placeholders: Vec<String> = (0..vals.len()).map(|_| "?".to_string()).collect();
118 let sql = format!(
119 "{} NOT IN ({})",
120 self.qualified_name(),
121 placeholders.join(", ")
122 );
123 Condition::multi(sql, vals)
124 }
125
126 pub fn is_null(self) -> Condition {
128 Condition::none(format!("{} IS NULL", self.qualified_name()))
129 }
130
131 pub fn is_not_null(self) -> Condition {
133 Condition::none(format!("{} IS NOT NULL", self.qualified_name()))
134 }
135
136 pub fn between(self, start: T, end: T) -> Condition {
138 let sql = format!("{} BETWEEN ? AND ?", self.qualified_name());
139 Condition::multi(sql, vec![start, end])
140 }
141
142 pub fn not_between(self, start: T, end: T) -> Condition {
144 let sql = format!("{} NOT BETWEEN ? AND ?", self.qualified_name());
145 Condition::multi(sql, vec![start, end])
146 }
147}