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