mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
98 lines
3.1 KiB
Rust
98 lines
3.1 KiB
Rust
use crate::database::Database;
|
|
use crate::error::Error;
|
|
use std::fmt::Debug;
|
|
|
|
pub trait Column: private_column::Sealed + 'static + Send + Sync + Debug {
|
|
type Database: Database;
|
|
|
|
/// Gets the column ordinal.
|
|
///
|
|
/// This can be used to unambiguously refer to this column within a row in case more than
|
|
/// one column have the same name
|
|
fn ordinal(&self) -> usize;
|
|
|
|
/// Gets the column name or alias.
|
|
///
|
|
/// The column name is unreliable (and can change between database minor versions) if this
|
|
/// column is an expression that has not been aliased.
|
|
fn name(&self) -> &str;
|
|
|
|
/// Gets the type information for the column.
|
|
fn type_info(&self) -> &<Self::Database as Database>::TypeInfo;
|
|
}
|
|
|
|
// Prevent users from implementing the `Row` trait.
|
|
pub(crate) mod private_column {
|
|
pub trait Sealed {}
|
|
}
|
|
|
|
/// A type that can be used to index into a [`Row`] or [`Statement`].
|
|
///
|
|
/// The [`get`] and [`try_get`] methods of [`Row`] accept any type that implements `ColumnIndex`.
|
|
/// This trait is implemented for strings which are used to look up a column by name, and for
|
|
/// `usize` which is used as a positional index into the row.
|
|
///
|
|
/// This trait is sealed and cannot be implemented for types outside of SQLx.
|
|
///
|
|
/// [`Row`]: crate::row::Row
|
|
/// [`Statement`]: crate::statement::Statement
|
|
/// [`get`]: crate::row::Row::get
|
|
/// [`try_get`]: crate::row::Row::try_get
|
|
///
|
|
pub trait ColumnIndex<T: ?Sized>: private_column_index::Sealed + Debug {
|
|
/// Returns a valid positional index into the row or statement, [`ColumnIndexOutOfBounds`], or,
|
|
/// [`ColumnNotFound`].
|
|
///
|
|
/// [`ColumnNotFound`]: ../enum.Error.html#variant.ColumnNotFound
|
|
/// [`ColumnIndexOutOfBounds`]: ../enum.Error.html#variant.ColumnIndexOutOfBounds
|
|
fn index(&self, container: &T) -> Result<usize, Error>;
|
|
}
|
|
|
|
impl<T: ?Sized, I: ColumnIndex<T> + ?Sized> ColumnIndex<T> for &'_ I {
|
|
#[inline]
|
|
fn index(&self, row: &T) -> Result<usize, Error> {
|
|
(**self).index(row)
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_column_index_for_row {
|
|
($R:ident) => {
|
|
impl crate::column::ColumnIndex<$R> for usize {
|
|
fn index(&self, row: &$R) -> Result<usize, crate::error::Error> {
|
|
let len = crate::row::Row::len(row);
|
|
|
|
if *self >= len {
|
|
return Err(crate::error::Error::ColumnIndexOutOfBounds { len, index: *self });
|
|
}
|
|
|
|
Ok(*self)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_column_index_for_statement {
|
|
($S:ident) => {
|
|
impl crate::column::ColumnIndex<$S<'_>> for usize {
|
|
fn index(&self, statement: &$S<'_>) -> Result<usize, crate::error::Error> {
|
|
let len = crate::statement::Statement::columns(statement).len();
|
|
|
|
if *self >= len {
|
|
return Err(crate::error::Error::ColumnIndexOutOfBounds { len, index: *self });
|
|
}
|
|
|
|
Ok(*self)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// Prevent users from implementing the `ColumnIndex` trait.
|
|
mod private_column_index {
|
|
pub trait Sealed {}
|
|
|
|
impl Sealed for usize {}
|
|
impl Sealed for str {}
|
|
impl<T> Sealed for &'_ T where T: Sealed + ?Sized {}
|
|
}
|