gatekeep_sqlx/fragment/
backend.rs1use super::{SqlxDriver, SqlxValue};
2use sqlx::QueryBuilder;
3use std::fmt::Debug;
4
5pub trait GatekeepSqlxBackend: Clone + Copy + Debug + Send + Sync + 'static {
7 type Database: sqlx::Database;
9
10 const DRIVER: SqlxDriver;
12
13 const NAME: &'static str;
15
16 fn push_placeholder(sql: &mut String, index: usize);
18
19 fn push_bind(builder: &mut QueryBuilder<Self::Database>, value: &SqlxValue);
21
22 const MIN_FUNCTION: &'static str;
24
25 const MAX_FUNCTION: &'static str;
27
28 const GRADE_FUNCTION_PROPAGATES_NULL: bool;
31}
32
33macro_rules! push_sqlx_bind {
34 ($builder:expr, $value:expr) => {
35 match $value {
36 SqlxValue::Bool(value) => {
37 $builder.push_bind(*value);
38 }
39 SqlxValue::I16(value) => {
40 $builder.push_bind(*value);
41 }
42 SqlxValue::I32(value) => {
43 $builder.push_bind(*value);
44 }
45 SqlxValue::I64(value) => {
46 $builder.push_bind(*value);
47 }
48 SqlxValue::Text(value) => {
49 $builder.push_bind(value.clone());
50 }
51 SqlxValue::Bytes(value) => {
52 $builder.push_bind(value.clone());
53 }
54 SqlxValue::Uuid(value) => {
55 $builder.push_bind(*value);
56 }
57 SqlxValue::Date(value) => {
58 $builder.push_bind(*value);
59 }
60 SqlxValue::Time(value) => {
61 $builder.push_bind(*value);
62 }
63 SqlxValue::Timestamp(value) => {
64 $builder.push_bind(*value);
65 }
66 SqlxValue::TimestampTz(value) => {
67 $builder.push_bind(*value);
68 }
69 }
70 };
71}
72
73#[cfg(feature = "postgres")]
75#[derive(Clone, Copy, Debug)]
76pub struct PostgresBackend;
77
78#[cfg(feature = "postgres")]
79impl GatekeepSqlxBackend for PostgresBackend {
80 type Database = sqlx::Postgres;
81
82 const DRIVER: SqlxDriver = SqlxDriver::Postgres;
83 const NAME: &'static str = "postgres";
84 const MIN_FUNCTION: &'static str = "LEAST";
85 const MAX_FUNCTION: &'static str = "GREATEST";
86 const GRADE_FUNCTION_PROPAGATES_NULL: bool = false;
87
88 fn push_placeholder(sql: &mut String, index: usize) {
89 sql.push('$');
90 sql.push_str(&index.to_string());
91 }
92
93 fn push_bind(builder: &mut QueryBuilder<Self::Database>, value: &SqlxValue) {
94 push_sqlx_bind!(builder, value);
95 }
96}
97
98#[cfg(feature = "sqlite")]
100#[derive(Clone, Copy, Debug)]
101pub struct SqliteBackend;
102
103#[cfg(feature = "sqlite")]
104impl GatekeepSqlxBackend for SqliteBackend {
105 type Database = sqlx::Sqlite;
106
107 const DRIVER: SqlxDriver = SqlxDriver::Sqlite;
108 const NAME: &'static str = "sqlite";
109 const MIN_FUNCTION: &'static str = "min";
110 const MAX_FUNCTION: &'static str = "max";
111 const GRADE_FUNCTION_PROPAGATES_NULL: bool = true;
112
113 fn push_placeholder(sql: &mut String, _index: usize) {
114 sql.push('?');
115 }
116
117 fn push_bind(builder: &mut QueryBuilder<Self::Database>, value: &SqlxValue) {
118 push_sqlx_bind!(builder, value);
119 }
120}
121
122#[cfg(feature = "mysql")]
124#[derive(Clone, Copy, Debug)]
125pub struct MySqlBackend;
126
127#[cfg(feature = "mysql")]
128impl GatekeepSqlxBackend for MySqlBackend {
129 type Database = sqlx::MySql;
130
131 const DRIVER: SqlxDriver = SqlxDriver::MySql;
132 const NAME: &'static str = "mysql";
133 const MIN_FUNCTION: &'static str = "LEAST";
134 const MAX_FUNCTION: &'static str = "GREATEST";
135 const GRADE_FUNCTION_PROPAGATES_NULL: bool = true;
136
137 fn push_placeholder(sql: &mut String, _index: usize) {
138 sql.push('?');
139 }
140
141 fn push_bind(builder: &mut QueryBuilder<Self::Database>, value: &SqlxValue) {
142 push_sqlx_bind!(builder, value);
143 }
144}