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;