@@ -20,7 +20,7 @@ use crate::sql_types::{self, HasSqlType};
2020/// protocol used to communicated with the database.
2121pub trait Backend
2222where
23- Self : Sized ,
23+ Self : Sized + SqlDialect ,
2424 Self : HasSqlType < sql_types:: SmallInt > ,
2525 Self : HasSqlType < sql_types:: Integer > ,
2626 Self : HasSqlType < sql_types:: BigInt > ,
@@ -73,19 +73,200 @@ pub trait BinaryRawValue<'a>: HasRawValue<'a> {
7373/// `FromSql`. Equivalent to `<DB as Backend>::RawValue<'a>`.
7474pub type RawValue < ' a , DB > = <DB as HasRawValue < ' a > >:: RawValue ;
7575
76- /// A trait indicating that implementing backend provides support for
77- /// `RETURNING` clauses .
76+ /// This trait provides various options to configure the
77+ /// generated SQL for a specific backend .
7878///
79- /// This trait has to be implemented in order to be able to use methods such as
80- /// `get_results` and `returning`. Namely, any method which leads to usage of
81- /// `RETURNING` clauses in SQL sent to backend will require that this trait
82- /// be implemented for used backend.
83- pub trait SupportsReturningClause { }
84- /// Does this backend support 'ON CONFLICT' clause?
85- pub trait SupportsOnConflictClause { }
86- /// Does this backend support 'WHERE' clauses on 'ON CONFLICT' clauses?
87- pub trait SupportsOnConflictTargetDecorations { }
88- /// Does this backend support the bare `DEFAULT` keyword?
89- pub trait SupportsDefaultKeyword { }
90- /// Does this backend use the standard `SAVEPOINT` syntax?
91- pub trait UsesAnsiSavepointSyntax { }
79+ /// Accessing anything from this trait is considered to be part of the
80+ /// public API. Implementing this trait is not considered to be part of
81+ /// diesels public API, as future versions of diesel may add additional
82+ /// associated constants here.
83+ ///
84+ /// Each associated type is used to configure the behaviour
85+ /// of one or more [`QueryFragment`](crate::query_builder::QueryFragment)
86+ /// implementations by providing
87+ /// a custom `QueryFragment<YourBackend, YourSpecialSyntaxType>` implementation
88+ /// to specialize on generic `QueryFragment<DB, DB::AssociatedType>` implementations.
89+ ///
90+ /// See the [`sql_dialect`] module for options provided by diesel out of the box.
91+ pub trait SqlDialect {
92+ /// Configures how this backends supports `RETURNING` clauses
93+ ///
94+ /// This allows backends to opt in `RETURNING` clause support and to
95+ /// provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
96+ /// implementation for [`ReturningClause`](crate::query_builder::ReturningClause)
97+ type ReturningClause ;
98+ /// Configures how this backend supports `ON CONFLICT` clauses
99+ ///
100+ /// This allows backends to opt in `ON CONFLICT` clause support
101+ type OnConflictClause ;
102+ /// Configures how this backend handles the bare `DEFAULT` keyword for
103+ /// inserting the default value in a `INSERT INTO` `VALUES` clause
104+ ///
105+ /// This allows backends to opt in support for `DEFAULT` value expressions
106+ /// for insert statements
107+ type InsertWithDefaultKeyword ;
108+ /// Configures how this backend handles Batch insert statements
109+ ///
110+ /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
111+ /// implementation for [`BatchInsert`](crate::query_builder::BatchInsert)
112+ type BatchInsertSupport ;
113+ /// Configures how this backend handles the `DEFAULT VALUES` clause for
114+ /// insert statements.
115+ ///
116+ /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
117+ /// implementation for [`DefaultValues`](crate::query_builder::DefaultValues)
118+ type DefaultValueClauseForInsert ;
119+ /// Configures how this backend handles empty `FROM` clauses for select statements.
120+ ///
121+ /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
122+ /// implementation for [`NoFromClause`](crate::query_builder::NoFromClause)
123+ type EmptyFromClauseSyntax ;
124+ /// Configures how this backend handles `EXISTS()` expressions.
125+ ///
126+ /// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
127+ /// implementation for [`Exists`](crate::expression::exists::Exists)
128+ type ExistsSyntax ;
129+
130+ /// Configures how this backend handles `IN()` and `NOT IN()` expressions.
131+ ///
132+ /// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
133+ /// implementations for [`In`](crate::expression::array_comparison::In),
134+ /// [`NotIn`](crate::expression::array_comparison::NotIn) and
135+ /// [`Many`](crate::expression::array_comparison::Many)
136+ type ArrayComparision ;
137+ }
138+
139+ /// This module contains all options provided by diesel to configure the [`SqlDialect`] trait.
140+ pub mod sql_dialect {
141+ #[ cfg( doc) ]
142+ use super :: SqlDialect ;
143+
144+ /// This module contains all diesel provided reusable options to
145+ /// configure [`SqlDialect::OnConflictClause`]
146+ pub mod on_conflict_clause {
147+ /// A marker trait indicating if a `ON CONFLICT` clause is supported or not
148+ ///
149+ /// If you use a custom type to specify specialized support for `ON CONFLICT` clauses
150+ /// implementing this trait opts into reusing diesels existing `ON CONFLICT`
151+ /// `QueryFragment` implementations
152+ pub trait SupportsOnConflictClause { }
153+
154+ /// This marker type indicates that `ON CONFLICT` clauses are not supported for this backend
155+ #[ derive( Debug , Copy , Clone ) ]
156+ pub struct DoesNotSupportOnConflictClause ;
157+ }
158+
159+ /// This module contains all reusable options to configure
160+ /// [`SqlDialect::ReturningClause`]
161+ pub mod returning_clause {
162+ /// A marker trait indicating if a `RETURNING` clause is supported or not
163+ ///
164+ /// If you use custom type to specify specialized support for `RETURNING` clauses
165+ /// implementing this trait opts in supporting `RETURNING` clause syntax
166+ pub trait SupportsReturningClause { }
167+
168+ /// Indicates that a backend provides support for `RETURNING` clauses
169+ /// using the postgresql `RETURNING` syntax
170+ #[ derive( Debug , Copy , Clone ) ]
171+ pub struct PgLikeReturningClause ;
172+
173+ /// Indicates that a backend does not support `RETURNING` clauses
174+ #[ derive( Debug , Copy , Clone ) ]
175+ pub struct DoesNotSupportReturningClause ;
176+
177+ impl SupportsReturningClause for PgLikeReturningClause { }
178+ }
179+
180+ /// This module contains all reusable options to configure
181+ /// [`SqlDialect::InsertWithDefaultKeyword`]
182+ pub mod default_keyword_for_insert {
183+ /// A marker trait indicating if a `DEFAULT` like expression
184+ /// is supported as part of `INSERT INTO` clauses to indicate
185+ /// that a default value should be inserted at a specific position
186+ ///
187+ /// If you use a custom type to specify specialized support for `DEFAULT`
188+ /// expressions implementing this trait opts in support for `DEFAULT`
189+ /// value expressions for inserts. Otherwise diesel will emulate this
190+ /// behaviour.
191+ pub trait SupportsDefaultKeyword { }
192+
193+ /// Indicates that a backend support `DEFAULT` value expressions
194+ /// for `INSERT INTO` statements based on the ISO SQL standard
195+ #[ derive( Debug , Copy , Clone ) ]
196+ pub struct IsoSqlDefaultKeyword ;
197+
198+ /// Indicates that a backend does not support `DEFAULT` value
199+ /// expressions0for `INSERT INTO` statements
200+ #[ derive( Debug , Copy , Clone ) ]
201+ pub struct DoesNotSupportDefaultKeyword ;
202+
203+ impl SupportsDefaultKeyword for IsoSqlDefaultKeyword { }
204+ }
205+
206+ /// This module contains all reusable options to configure
207+ /// [`SqlDialect::BatchInsertSupport`]
208+ pub mod batch_insert_support {
209+ /// A marker trait indicating if batch insert statements
210+ /// are supported for this backend or not
211+ pub trait SupportsBatchInsert { }
212+
213+ /// Indicates that this backend does not support batch
214+ /// insert statements.
215+ /// In this case diesel will emulate batch insert support
216+ /// by inserting each row on it's own
217+ #[ derive( Debug , Copy , Clone ) ]
218+ pub struct DoesNotSupportBatchInsert ;
219+
220+ /// Indicates that this backend supports postgres style
221+ /// batch insert statements to insert multiple rows using one
222+ /// insert statement
223+ #[ derive( Debug , Copy , Clone ) ]
224+ pub struct PostgresLikeBatchInsertSupport ;
225+
226+ impl SupportsBatchInsert for PostgresLikeBatchInsertSupport { }
227+ }
228+
229+ /// This module contains all reusable options to configure
230+ /// [`SqlDialect::DefaultValueClauseForInsert`]
231+ pub mod default_value_clause {
232+
233+ /// Indicates that this backend uses the
234+ /// `DEFAULT VALUES` syntax to specify
235+ /// that a row consisting only of default
236+ /// values should be inserted
237+ #[ derive( Debug , Clone , Copy ) ]
238+ pub struct AnsiDefaultValueClause ;
239+ }
240+
241+ /// This module contains all reusable options to configure
242+ /// [`SqlDialect::EmptyFromClauseSyntax`]
243+ pub mod from_clause_syntax {
244+
245+ /// Indicates that this backend skips
246+ /// the `FROM` clause in `SELECT` statements
247+ /// if no table/view is queried
248+ #[ derive( Debug , Copy , Clone ) ]
249+ pub struct AnsiSqlFromClauseSyntax ;
250+ }
251+
252+ /// This module contains all reusable options to configure
253+ /// [`SqlDialect::ExistsSyntax`]
254+ pub mod exists_syntax {
255+
256+ /// Indicates that this backend
257+ /// treats `EXIST()` as function
258+ /// like expression
259+ #[ derive( Debug , Copy , Clone ) ]
260+ pub struct AnsiSqlExistsSyntax ;
261+ }
262+
263+ /// This module contains all reusable options to configure
264+ /// [`SqlDialect::ArrayComparision`]
265+ pub mod array_comparision {
266+
267+ /// Indicates that this backend requires a single bind
268+ /// per array element in `IN()` and `NOT IN()` expression
269+ #[ derive( Debug , Copy , Clone ) ]
270+ pub struct AnsiSqlArrayComparison ;
271+ }
272+ }
0 commit comments