Skip to main content

ruststream_sqlx_dialect/opening/
level.rs

1/// [`Isolation::ReadUncommitted`](crate::Isolation::ReadUncommitted) as a type, for the bound
2/// [`Opens`](crate::Opens) sets.
3///
4/// # Examples
5///
6/// ```
7/// # use std::num::NonZeroUsize;
8/// # use ruststream_sqlx_dialect::TableName;
9/// use ruststream_sqlx_dialect::{
10///     Dialect, Isolation, Opening, Opens, Statement, StatementError, TableSpec, level,
11/// };
12///
13/// /// SQL Server, a database without a built-in dialect.
14/// #[derive(Debug)]
15/// pub struct Mssql;
16///
17/// impl Dialect for Mssql {
18///     fn name(&self) -> &'static str {
19///         "mssql"
20///     }
21///
22///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
23///         match opening {
24///             Opening::Default => Ok(Some(
25///                 "SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRANSACTION",
26///             )),
27///             Opening::Isolation(Isolation::ReadUncommitted) => Ok(Some(
28///                 "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; BEGIN TRANSACTION",
29///             )),
30///             other => Err(StatementError::UnsupportedOpening {
31///                 dialect: self.name(),
32///                 opening: other.name(),
33///             }),
34///         }
35///     }
36/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('['); out.push_str(&ident.replace(']', "]]")); out.push(']'); }
37/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push_str("@p"); out.push_str(&index.to_string()); }
38/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
39/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
40/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
41/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
42/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
43/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
44/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
45/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
46/// }
47///
48/// // A table with `isolation = read_uncommitted` mounts on `Mssql`.
49/// impl Opens<level::ReadUncommitted> for Mssql {}
50/// ```
51#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
52pub struct ReadUncommitted;
53
54/// [`Isolation::ReadCommitted`](crate::Isolation::ReadCommitted) as a type, for the bound
55/// [`Opens`](crate::Opens) sets.
56///
57/// # Examples
58///
59/// ```
60/// # use std::num::NonZeroUsize;
61/// # use ruststream_sqlx_dialect::TableName;
62/// use ruststream_sqlx_dialect::{
63///     Dialect, Isolation, Opening, Opens, Statement, StatementError, TableSpec, level,
64/// };
65///
66/// /// SQL Server, a database without a built-in dialect.
67/// #[derive(Debug)]
68/// pub struct Mssql;
69///
70/// impl Dialect for Mssql {
71///     fn name(&self) -> &'static str {
72///         "mssql"
73///     }
74///
75///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
76///         match opening {
77///             Opening::Default | Opening::Isolation(Isolation::ReadCommitted) => Ok(Some(
78///                 "SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRANSACTION",
79///             )),
80///             other => Err(StatementError::UnsupportedOpening {
81///                 dialect: self.name(),
82///                 opening: other.name(),
83///             }),
84///         }
85///     }
86/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('['); out.push_str(&ident.replace(']', "]]")); out.push(']'); }
87/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push_str("@p"); out.push_str(&index.to_string()); }
88/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
89/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
90/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
91/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
92/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
93/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
94/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
95/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
96/// }
97///
98/// // A table with `isolation = read_committed` mounts on `Mssql`.
99/// impl Opens<level::ReadCommitted> for Mssql {}
100/// ```
101#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
102pub struct ReadCommitted;
103
104/// [`Isolation::RepeatableRead`](crate::Isolation::RepeatableRead) as a type, for the bound
105/// [`Opens`](crate::Opens) sets.
106///
107/// # Examples
108///
109/// ```
110/// # use std::num::NonZeroUsize;
111/// # use ruststream_sqlx_dialect::TableName;
112/// use ruststream_sqlx_dialect::{
113///     Dialect, Isolation, Opening, Opens, Statement, StatementError, TableSpec, level,
114/// };
115///
116/// /// SQL Server, a database without a built-in dialect.
117/// #[derive(Debug)]
118/// pub struct Mssql;
119///
120/// impl Dialect for Mssql {
121///     fn name(&self) -> &'static str {
122///         "mssql"
123///     }
124///
125///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
126///         match opening {
127///             Opening::Default => Ok(Some(
128///                 "SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRANSACTION",
129///             )),
130///             Opening::Isolation(Isolation::RepeatableRead) => Ok(Some(
131///                 "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN TRANSACTION",
132///             )),
133///             other => Err(StatementError::UnsupportedOpening {
134///                 dialect: self.name(),
135///                 opening: other.name(),
136///             }),
137///         }
138///     }
139/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('['); out.push_str(&ident.replace(']', "]]")); out.push(']'); }
140/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push_str("@p"); out.push_str(&index.to_string()); }
141/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
142/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
143/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
144/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
145/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
146/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
147/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
148/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
149/// }
150///
151/// // A table with `isolation = repeatable_read` mounts on `Mssql`.
152/// impl Opens<level::RepeatableRead> for Mssql {}
153/// ```
154#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
155pub struct RepeatableRead;
156
157/// [`Isolation::Serializable`](crate::Isolation::Serializable) as a type, for the bound
158/// [`Opens`](crate::Opens) sets.
159///
160/// # Examples
161///
162/// ```
163/// # use std::num::NonZeroUsize;
164/// # use ruststream_sqlx_dialect::TableName;
165/// use ruststream_sqlx_dialect::{
166///     Dialect, Isolation, Opening, Opens, Statement, StatementError, TableSpec, level,
167/// };
168///
169/// /// SQL Server, a database without a built-in dialect.
170/// #[derive(Debug)]
171/// pub struct Mssql;
172///
173/// impl Dialect for Mssql {
174///     fn name(&self) -> &'static str {
175///         "mssql"
176///     }
177///
178///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
179///         match opening {
180///             Opening::Default => Ok(Some(
181///                 "SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRANSACTION",
182///             )),
183///             Opening::Isolation(Isolation::Serializable) => Ok(Some(
184///                 "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION",
185///             )),
186///             other => Err(StatementError::UnsupportedOpening {
187///                 dialect: self.name(),
188///                 opening: other.name(),
189///             }),
190///         }
191///     }
192/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('['); out.push_str(&ident.replace(']', "]]")); out.push(']'); }
193/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push_str("@p"); out.push_str(&index.to_string()); }
194/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
195/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
196/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
197/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
198/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
199/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
200/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
201/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
202/// }
203///
204/// // A table with `isolation = serializable` mounts on `Mssql`.
205/// impl Opens<level::Serializable> for Mssql {}
206/// ```
207#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
208pub struct Serializable;
209
210/// [`Mode::Deferred`](crate::Mode::Deferred) as a type, for the bound
211/// [`Opens`](crate::Opens) sets.
212///
213/// # Examples
214///
215/// ```
216/// # use std::num::NonZeroUsize;
217/// # use ruststream_sqlx_dialect::TableName;
218/// use ruststream_sqlx_dialect::{
219///     Dialect, Mode, Opening, Opens, Statement, StatementError, TableSpec, level,
220/// };
221///
222/// /// libSQL, a fork of SQLite served over the network, a database without a built-in dialect.
223/// #[derive(Debug)]
224/// pub struct Libsql;
225///
226/// impl Dialect for Libsql {
227///     fn name(&self) -> &'static str {
228///         "libsql"
229///     }
230///
231///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
232///         match opening {
233///             Opening::Default => Ok(None),
234///             Opening::Mode(Mode::Deferred) => Ok(Some("BEGIN DEFERRED")),
235///             other => Err(StatementError::UnsupportedOpening {
236///                 dialect: self.name(),
237///                 opening: other.name(),
238///             }),
239///         }
240///     }
241/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('"'); out.push_str(&ident.replace('"', "\"\"")); out.push('"'); }
242/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push('?'); out.push_str(&index.to_string()); }
243/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
244/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
245/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
246/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
247/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
248/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
249/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
250/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
251/// }
252///
253/// // A table with `mode = deferred` mounts on `Libsql`.
254/// impl Opens<level::Deferred> for Libsql {}
255/// ```
256#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
257pub struct Deferred;
258
259/// [`Mode::Immediate`](crate::Mode::Immediate) as a type, for the bound
260/// [`Opens`](crate::Opens) sets.
261///
262/// # Examples
263///
264/// ```
265/// # use std::num::NonZeroUsize;
266/// # use ruststream_sqlx_dialect::TableName;
267/// use ruststream_sqlx_dialect::{
268///     Dialect, Mode, Opening, Opens, Statement, StatementError, TableSpec, level,
269/// };
270///
271/// /// libSQL, a fork of SQLite served over the network, a database without a built-in dialect.
272/// #[derive(Debug)]
273/// pub struct Libsql;
274///
275/// impl Dialect for Libsql {
276///     fn name(&self) -> &'static str {
277///         "libsql"
278///     }
279///
280///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
281///         match opening {
282///             Opening::Default => Ok(None),
283///             Opening::Mode(Mode::Immediate) => Ok(Some("BEGIN IMMEDIATE")),
284///             other => Err(StatementError::UnsupportedOpening {
285///                 dialect: self.name(),
286///                 opening: other.name(),
287///             }),
288///         }
289///     }
290/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('"'); out.push_str(&ident.replace('"', "\"\"")); out.push('"'); }
291/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push('?'); out.push_str(&index.to_string()); }
292/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
293/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
294/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
295/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
296/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
297/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
298/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
299/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
300/// }
301///
302/// // A table with `mode = immediate` mounts on `Libsql`.
303/// impl Opens<level::Immediate> for Libsql {}
304/// ```
305#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
306pub struct Immediate;
307
308/// [`Mode::Exclusive`](crate::Mode::Exclusive) as a type, for the bound
309/// [`Opens`](crate::Opens) sets.
310///
311/// # Examples
312///
313/// ```
314/// # use std::num::NonZeroUsize;
315/// # use ruststream_sqlx_dialect::TableName;
316/// use ruststream_sqlx_dialect::{
317///     Dialect, Mode, Opening, Opens, Statement, StatementError, TableSpec, level,
318/// };
319///
320/// /// libSQL, a fork of SQLite served over the network, a database without a built-in dialect.
321/// #[derive(Debug)]
322/// pub struct Libsql;
323///
324/// impl Dialect for Libsql {
325///     fn name(&self) -> &'static str {
326///         "libsql"
327///     }
328///
329///     fn begin(&self, opening: Opening) -> Result<Option<&'static str>, StatementError> {
330///         match opening {
331///             Opening::Default => Ok(None),
332///             Opening::Mode(Mode::Exclusive) => Ok(Some("BEGIN EXCLUSIVE")),
333///             other => Err(StatementError::UnsupportedOpening {
334///                 dialect: self.name(),
335///                 opening: other.name(),
336///             }),
337///         }
338///     }
339/// #     fn quote_into(&self, ident: &str, out: &mut String) { out.push('"'); out.push_str(&ident.replace('"', "\"\"")); out.push('"'); }
340/// #     fn placeholder_into(&self, index: NonZeroUsize, out: &mut String) { out.push('?'); out.push_str(&index.to_string()); }
341/// #     fn fetch(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedFetch { dialect: self.name() }) }
342/// #     fn ack(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
343/// #     fn retry(&self, spec: &TableSpec<'_>) -> Result<Option<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
344/// #     fn retry_after(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
345/// #     fn discard(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
346/// #     fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
347/// #     fn dead_letter_table(&self, spec: &TableSpec<'_>, target: TableName<'_>) -> Result<Vec<Statement>, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
348/// #     fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> { Err(StatementError::UnsupportedForm { dialect: self.name(), form: spec.form().name() }) }
349/// }
350///
351/// // A table with `mode = exclusive` mounts on `Libsql`.
352/// impl Opens<level::Exclusive> for Libsql {}
353/// ```
354#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
355pub struct Exclusive;