pub struct Column<'a> { /* private fields */ }Expand description
One column of a queue table: its name in the database, and whether the database fills it in.
§Examples
use ruststream_sqlx_dialect::{
ClaimShape, Dialect, Form, Lease, Param, Statement, StatementError, TableSpec,
};
/// SQL Server, a database without a built-in dialect, recording when a handler last extended
/// its lease: every lease table of the service has a `seen_at` column.
#[derive(Debug)]
pub struct Mssql;
impl Lease for Mssql {
fn extend(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> {
// The lease form carries the column of its expiry.
let Form::Lease(expiry) = spec.form() else {
return Err(StatementError::FormMismatch {
statement: "extend",
form: spec.form().name(),
});
};
let mut sql = String::from("UPDATE ");
self.quote_into(spec.table(), &mut sql);
sql.push_str(" SET ");
self.quote_into(expiry.name(), &mut sql);
sql.push_str(" = @p1, [seen_at] = @p2 WHERE ");
self.quote_into(spec.id().name(), &mut sql);
sql.push_str(" = @p3 AND ");
self.quote_into(expiry.name(), &mut sql);
sql.push_str(" = @p4");
Ok(Statement::new(sql, [Param::Lease, Param::Now, Param::Id, Param::Held]))
}
}Implementations§
Source§impl<'a> Column<'a>
impl<'a> Column<'a>
Sourcepub const fn new(name: &'a str) -> Self
pub const fn new(name: &'a str) -> Self
A column the service writes.
#[derive(Inbox)] names the column of each field with it.
§Examples
use ruststream_sqlx_dialect::insert::{self, Sql};
use ruststream_sqlx_dialect::{Column, Form, TableSpec};
// email_jobs: job_id BIGINT PRIMARY KEY, payload BYTEA; the service writes both.
const EMAILS: TableSpec<'static> =
TableSpec::new("email_jobs", Column::new("job_id"), Form::RowLock)
.payload(Column::new("payload"));
const INSERT: Sql<128> = insert::postgres(&EMAILS);
assert_eq!(INSERT.as_str(), r#"INSERT INTO "email_jobs" ("job_id", "payload") VALUES ($1, $2)"#);Sourcepub const fn generated(self) -> Self
pub const fn generated(self) -> Self
The same column, filled in by the database, so an insert leaves it out.
#[field(generated)] on a field sets it, as #[field(id, generated)] does on a
sequence’s id.
§Examples
use ruststream_sqlx_dialect::insert::{self, Sql};
use ruststream_sqlx_dialect::{Column, Form, TableSpec};
// email_jobs: job_id BIGSERIAL PRIMARY KEY, payload BYTEA; the sequence numbers the rows.
const EMAILS: TableSpec<'static> =
TableSpec::new("email_jobs", Column::new("job_id").generated(), Form::RowLock)
.payload(Column::new("payload"));
const INSERT: Sql<128> = insert::postgres(&EMAILS);
assert_eq!(INSERT.as_str(), r#"INSERT INTO "email_jobs" ("payload") VALUES ($1)"#);Sourcepub const fn name(&self) -> &'a str
pub const fn name(&self) -> &'a str
The column’s name in the database.
§Examples
use ruststream_sqlx_dialect::{Dialect, Param, Role, Statement, StatementError, TableSpec};
/// SQL Server, a database without a built-in dialect; the service's tables take their rows
/// by row lock.
#[derive(Debug)]
pub struct Mssql;
impl Dialect for Mssql {
fn name(&self) -> &'static str {
"mssql"
}
// A dead letter starts its new group with the attempt count of a new row.
fn dead_letter_group(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> {
let Some(group) = spec.column(Role::Group) else {
return Err(StatementError::MissingRole {
statement: "dead_letter_group",
role: Role::Group,
});
};
let mut sql = String::from("UPDATE ");
self.quote_into(spec.table(), &mut sql);
sql.push_str(" SET ");
self.quote_into(group.name(), &mut sql);
sql.push_str(" = @p1");
if let Some(attempt) = spec.column(Role::Attempt) {
sql.push_str(", ");
self.quote_into(attempt.name(), &mut sql);
sql.push_str(" = DEFAULT");
}
sql.push_str(" WHERE ");
self.quote_into(spec.id().name(), &mut sql);
sql.push_str(" = @p2");
Ok(Statement::new(sql, [Param::Destination, Param::Id]))
}
}Sourcepub const fn is_generated(&self) -> bool
pub const fn is_generated(&self) -> bool
Whether the database fills the column in, so an insert leaves it out.
§Examples
use std::num::NonZeroUsize;
use ruststream_sqlx_dialect::{Dialect, Param, Statement, StatementError, TableSpec};
/// SQL Server, a database without a built-in dialect.
#[derive(Debug)]
pub struct Mssql;
impl Dialect for Mssql {
fn name(&self) -> &'static str {
"mssql"
}
fn insert(&self, spec: &TableSpec<'_>) -> Result<Statement, StatementError> {
if spec.selects_all() {
return Err(StatementError::Flattened { statement: "insert" });
}
let mut names = String::new();
let mut values = String::new();
let mut params = Vec::new();
// Every column the database does not fill, bound by its position in the
// description.
for (index, column) in spec.columns().enumerate() {
if column.is_generated() {
continue;
}
if !params.is_empty() {
names.push_str(", ");
values.push_str(", ");
}
self.quote_into(column.name(), &mut names);
let position = NonZeroUsize::MIN.saturating_add(params.len());
self.placeholder_into(position, &mut values);
params.push(Param::Column(index));
}
let mut table = String::new();
self.quote_into(spec.table(), &mut table);
let sql = format!("INSERT INTO {table} ({names}) VALUES ({values})");
Ok(Statement::new(sql, params))
}
}Trait Implementations§
impl<'a> Copy for Column<'a>
impl<'a> Eq for Column<'a>
impl<'a> StructuralPartialEq for Column<'a>
Auto Trait Implementations§
impl<'a> Freeze for Column<'a>
impl<'a> RefUnwindSafe for Column<'a>
impl<'a> Send for Column<'a>
impl<'a> Sync for Column<'a>
impl<'a> Unpin for Column<'a>
impl<'a> UnsafeUnpin for Column<'a>
impl<'a> UnwindSafe for Column<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more