1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
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`]: Error::ColumnNotFound
/// [`ColumnIndexOutOfBounds`]: Error::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 {}
}