mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-30 13:20:59 +00:00
* refactor: introduce `SqlSafeStr` API * rebase main * Add SqlStr + remove Statement lifetime * Update the definition of Executor and AnyConnectionBackend + update Postgres driver * Update MySql driver * Update Sqlite driver * remove debug clone count * Reduce the amount of SqlStr clones * improve QueryBuilder error message * cargo fmt * fix clippy warnings * fix doc test * Avoid panic in `QueryBuilder::reset` * Use `QueryBuilder` when removing all test db's * Add comment to `SqlStr` Co-authored-by: Austin Bonander <austin.bonander@gmail.com> * Update sqlx-core/src/query_builder.rs Co-authored-by: Austin Bonander <austin.bonander@gmail.com> * Add `Clone` as supertrait to `Statement` * Move `Connection`, `AnyConnectionBackend` and `TransactionManager` to `SqlStr` * Replace `sql_cloned` with `sql` in `Statement` * Update `Executor` trait * Update unit tests + QueryBuilder changes * Remove code in comments * Update comment in `QueryBuilder` * Fix clippy warnings * Update `Migrate` comment * Small changes * Move `Migration` to `SqlStr` --------- Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
141 lines
4.8 KiB
Rust
141 lines
4.8 KiB
Rust
use crate::database::Database;
|
|
use crate::error::Error;
|
|
|
|
use std::fmt::Debug;
|
|
use std::sync::Arc;
|
|
|
|
pub trait Column: 'static + Send + Sync + Debug {
|
|
type Database: Database<Column = Self>;
|
|
|
|
/// 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;
|
|
|
|
/// If this column comes from a table, return the table and original column name.
|
|
///
|
|
/// Returns [`ColumnOrigin::Expression`] if the column is the result of an expression
|
|
/// or else the source table could not be determined.
|
|
///
|
|
/// Returns [`ColumnOrigin::Unknown`] if the database driver does not have that information,
|
|
/// or has not overridden this method.
|
|
// This method returns an owned value instead of a reference,
|
|
// to give the implementor more flexibility.
|
|
fn origin(&self) -> ColumnOrigin {
|
|
ColumnOrigin::Unknown
|
|
}
|
|
}
|
|
|
|
/// A [`Column`] that originates from a table.
|
|
#[derive(Debug, Clone)]
|
|
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
|
|
pub struct TableColumn {
|
|
/// The name of the table (optionally schema-qualified) that the column comes from.
|
|
pub table: Arc<str>,
|
|
/// The original name of the column.
|
|
pub name: Arc<str>,
|
|
}
|
|
|
|
/// The possible statuses for our knowledge of the origin of a [`Column`].
|
|
#[derive(Debug, Clone, Default)]
|
|
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
|
|
pub enum ColumnOrigin {
|
|
/// The column is known to originate from a table.
|
|
///
|
|
/// Included is the table name and original column name.
|
|
Table(TableColumn),
|
|
/// The column originates from an expression, or else its origin could not be determined.
|
|
Expression,
|
|
/// The database driver does not know the column origin at this time.
|
|
///
|
|
/// This may happen if:
|
|
/// * The connection is in the middle of executing a query,
|
|
/// and cannot query the catalog to fetch this information.
|
|
/// * The connection does not have access to the database catalog.
|
|
/// * The implementation of [`Column`] did not override [`Column::origin()`].
|
|
#[default]
|
|
Unknown,
|
|
}
|
|
|
|
impl ColumnOrigin {
|
|
/// Returns the true column origin, if known.
|
|
pub fn table_column(&self) -> Option<&TableColumn> {
|
|
if let Self::Table(table_column) = self {
|
|
Some(table_column)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 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.
|
|
///
|
|
/// [`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>: 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_export]
|
|
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_export]
|
|
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)
|
|
}
|
|
}
|
|
};
|
|
}
|