sea_query_rusqlite/
lib.rs1#![forbid(unsafe_code)]
2
3use rusqlite::{
4 Result, ToSql,
5 types::{Null, ToSqlOutput},
6};
7use sea_query::Value;
8use sea_query::{QueryBuilder, query::*};
9
10#[derive(Clone, Debug, PartialEq)]
11pub struct RusqliteValue(pub sea_query::Value);
12#[derive(Clone, Debug, PartialEq)]
13pub struct RusqliteValues(pub Vec<RusqliteValue>);
14
15impl RusqliteValues {
16 pub fn as_params(&self) -> Vec<&dyn ToSql> {
17 self.0
18 .iter()
19 .map(|x| {
20 let y: &dyn ToSql = x;
21 y
22 })
23 .collect()
24 }
25}
26
27pub trait RusqliteBinder {
28 fn build_rusqlite<T: QueryBuilder>(&self, query_builder: T) -> (String, RusqliteValues);
29}
30
31macro_rules! impl_rusqlite_binder {
32 ($l:ident) => {
33 impl RusqliteBinder for $l {
34 fn build_rusqlite<T: QueryBuilder>(
35 &self,
36 query_builder: T,
37 ) -> (String, RusqliteValues) {
38 let (query, values) = self.build(query_builder);
39 (
40 query,
41 RusqliteValues(values.into_iter().map(RusqliteValue).collect()),
42 )
43 }
44 }
45 };
46}
47
48impl_rusqlite_binder!(SelectStatement);
49impl_rusqlite_binder!(UpdateStatement);
50impl_rusqlite_binder!(InsertStatement);
51impl_rusqlite_binder!(DeleteStatement);
52impl_rusqlite_binder!(WithQuery);
53
54impl ToSql for RusqliteValue {
55 fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
56 macro_rules! box_to_sql {
57 ( $v: expr ) => {
58 match $v {
59 Some(v) => v.to_sql(),
60 None => Null.to_sql(),
61 }
62 };
63 }
64
65 macro_rules! opt_string_to_sql {
66 ( $v: expr ) => {
67 match $v {
68 Some(v) => Ok(ToSqlOutput::from(v)),
69 None => Null.to_sql(),
70 }
71 };
72 }
73
74 match &self.0 {
75 Value::Bool(v) => v.to_sql(),
76 Value::TinyInt(v) => v.to_sql(),
77 Value::SmallInt(v) => v.to_sql(),
78 Value::Int(v) => v.to_sql(),
79 Value::BigInt(v) => v.to_sql(),
80 Value::TinyUnsigned(v) => v.to_sql(),
81 Value::SmallUnsigned(v) => v.to_sql(),
82 Value::Unsigned(v) => v.to_sql(),
83 Value::BigUnsigned(v) => v.to_sql(),
84 Value::Float(v) => v.to_sql(),
85 Value::Double(v) => v.to_sql(),
86 Value::String(v) => match v {
87 Some(v) => v.as_str().to_sql(),
88 None => Null.to_sql(),
89 },
90 Value::Char(v) => opt_string_to_sql!(v.map(|v| v.to_string())),
91 Value::Bytes(v) => match v {
92 Some(v) => v.as_slice().to_sql(),
93 None => Null.to_sql(),
94 },
95 #[cfg(feature = "with-chrono")]
96 Value::ChronoDate(v) => v.to_sql(),
97 #[cfg(feature = "with-chrono")]
98 Value::ChronoTime(v) => v.to_sql(),
99 #[cfg(feature = "with-chrono")]
100 Value::ChronoDateTime(v) => v.to_sql(),
101 #[cfg(feature = "with-chrono")]
102 Value::ChronoDateTimeUtc(v) => v.to_sql(),
103 #[cfg(feature = "with-chrono")]
104 Value::ChronoDateTimeLocal(v) => v.to_sql(),
105 #[cfg(feature = "with-chrono")]
106 Value::ChronoDateTimeWithTimeZone(v) => v.to_sql(),
107 #[cfg(feature = "with-time")]
108 v @ Value::TimeDate(_) => opt_string_to_sql!(v.time_as_naive_utc_in_string()),
109 #[cfg(feature = "with-time")]
110 v @ Value::TimeTime(_) => opt_string_to_sql!(v.time_as_naive_utc_in_string()),
111 #[cfg(feature = "with-time")]
112 v @ Value::TimeDateTime(_) => opt_string_to_sql!(v.time_as_naive_utc_in_string()),
113 #[cfg(feature = "with-time")]
114 v @ Value::TimeDateTimeWithTimeZone(_) => {
115 opt_string_to_sql!(v.time_as_naive_utc_in_string())
116 }
117 #[cfg(feature = "with-uuid")]
118 Value::Uuid(v) => v.to_sql(),
119 #[cfg(feature = "with-json")]
120 Value::Json(j) => box_to_sql!(j),
121 #[cfg(feature = "with-rust_decimal")]
122 Value::Decimal(_) => {
123 panic!("Rusqlite doesn't support rust_decimal arguments");
124 }
125 #[cfg(feature = "with-bigdecimal")]
126 Value::BigDecimal(_) => {
127 panic!("Rusqlite doesn't support bigdecimal arguments");
128 }
129 #[cfg(feature = "with-ipnetwork")]
130 Value::IpNetwork(_) => {
131 panic!("Rusqlite doesn't support IpNetwork arguments");
132 }
133 #[cfg(feature = "with-mac_address")]
134 Value::MacAddress(_) => {
135 panic!("Rusqlite doesn't support MacAddress arguments");
136 }
137 #[cfg(feature = "postgres-array")]
138 Value::Array(_, _) => {
139 panic!("Rusqlite doesn't support Array arguments");
140 }
141 #[cfg(feature = "postgres-vector")]
142 Value::Vector(_) => {
143 panic!("Rusqlite doesn't support Vector arguments");
144 }
145 }
146 }
147}