diff --git a/sqlx-core/src/cursor.rs b/sqlx-core/src/cursor.rs index 559c8554..d46c063c 100644 --- a/sqlx-core/src/cursor.rs +++ b/sqlx-core/src/cursor.rs @@ -2,9 +2,10 @@ use futures_core::future::BoxFuture; -use crate::database::{Database, HasRow}; +use crate::database::Database; use crate::executor::Execute; use crate::pool::Pool; +use crate::row::HasRow; /// Represents a result set, which is generated by executing a query against the database. /// @@ -70,3 +71,18 @@ where pub(crate) mod private { pub trait Sealed {} } + +/// Associate [`Database`] with a [`Cursor`] of a generic lifetime. +/// +/// --- +/// +/// The upcoming Rust feature, [Generic Associated Types], should obviate +/// the need for this trait. +/// +/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 +pub trait HasCursor<'c, 'q> { + type Database: Database; + + /// The concrete `Cursor` implementation for this database. + type Cursor: Cursor<'c, 'q, Database = Self::Database>; +} diff --git a/sqlx-core/src/database.rs b/sqlx-core/src/database.rs index 690be2c1..87119102 100644 --- a/sqlx-core/src/database.rs +++ b/sqlx-core/src/database.rs @@ -2,10 +2,11 @@ use std::fmt::{Debug, Display}; use crate::arguments::Arguments; use crate::connection::Connect; -use crate::cursor::Cursor; +use crate::cursor::HasCursor; use crate::error::DatabaseError; -use crate::row::Row; +use crate::row::HasRow; use crate::types::TypeInfo; +use crate::value::HasRawValue; /// A database driver. /// @@ -13,11 +14,10 @@ use crate::types::TypeInfo; /// database (e.g., **MySQL**, **Postgres**). pub trait Database where - Self: Sized + Send + 'static, + Self: Debug + Sized + Send + 'static, Self: for<'c> HasRow<'c, Database = Self>, - Self: for<'c> HasRawValue<'c>, + Self: for<'c> HasRawValue<'c, Database = Self>, Self: for<'c, 'q> HasCursor<'c, 'q, Database = Self>, - Self: Debug, { /// The concrete `Connection` implementation for this database. type Connection: Connect; @@ -33,55 +33,10 @@ where /// The Rust type used as the buffer when encoding arguments. /// - /// For example, **Postgres** and **MySQL** use `Vec`; however, **SQLite** uses `Vec`. + /// For example, **Postgres** and **MySQL** use `Vec`; + /// however, **SQLite** uses `Vec`. type RawBuffer: Default; /// The concrete `DatabaseError` type used to report errors from the database. type Error: DatabaseError + Send + Sync; } - -/// Associate [`Database`] with a `RawValue` of a generic lifetime. -/// -/// --- -/// -/// The upcoming Rust feature, [Generic Associated Types], should obviate -/// the need for this trait. -/// -/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 -pub trait HasRawValue<'c> { - /// The Rust type used to hold a not-yet-decoded value that has just been - /// received from the database. - /// - /// For example, **Postgres** and **MySQL** use `&'c [u8]`; however, **SQLite** uses `SqliteValue<'c>`. - type RawValue; -} - -/// Associate [`Database`] with a [`Cursor`] of a generic lifetime. -/// -/// --- -/// -/// The upcoming Rust feature, [Generic Associated Types], should obviate -/// the need for this trait. -/// -/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 -pub trait HasCursor<'c, 'q> { - type Database: Database; - - /// The concrete `Cursor` implementation for this database. - type Cursor: Cursor<'c, 'q, Database = Self::Database>; -} - -/// Associate [`Database`] with a [`Row`] of a generic lifetime. -/// -/// --- -/// -/// The upcoming Rust feature, [Generic Associated Types], should obviate -/// the need for this trait. -/// -/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 -pub trait HasRow<'c> { - type Database: Database; - - /// The concrete `Row` implementation for this database. - type Row: Row<'c, Database = Self::Database>; -} diff --git a/sqlx-core/src/decode.rs b/sqlx-core/src/decode.rs index 81b23025..b851ef1c 100644 --- a/sqlx-core/src/decode.rs +++ b/sqlx-core/src/decode.rs @@ -1,6 +1,7 @@ //! Types and traits for decoding values from the database. -use crate::database::{Database, HasRawValue}; +use crate::database::Database; +use crate::value::HasRawValue; /// A type that can be decoded from the database. pub trait Decode<'de, DB> diff --git a/sqlx-core/src/executor.rs b/sqlx-core/src/executor.rs index 573ec705..3008c3c3 100644 --- a/sqlx-core/src/executor.rs +++ b/sqlx-core/src/executor.rs @@ -1,6 +1,7 @@ use futures_core::future::BoxFuture; -use crate::database::{Database, HasCursor}; +use crate::cursor::HasCursor; +use crate::database::Database; use crate::describe::Describe; /// A type that contains or can provide a database connection to use for executing queries diff --git a/sqlx-core/src/lib.rs b/sqlx-core/src/lib.rs index dbae4e6b..93598a9d 100644 --- a/sqlx-core/src/lib.rs +++ b/sqlx-core/src/lib.rs @@ -25,6 +25,7 @@ mod io; pub mod connection; pub mod cursor; pub mod database; +pub mod value; #[macro_use] pub mod executor; diff --git a/sqlx-core/src/pool/executor.rs b/sqlx-core/src/pool/executor.rs index ebf18a9b..639c76a9 100644 --- a/sqlx-core/src/pool/executor.rs +++ b/sqlx-core/src/pool/executor.rs @@ -2,8 +2,8 @@ use futures_core::future::BoxFuture; use super::PoolConnection; use crate::connection::Connect; -use crate::cursor::Cursor; -use crate::database::{Database, HasCursor}; +use crate::cursor::{Cursor, HasCursor}; +use crate::database::Database; use crate::describe::Describe; use crate::executor::Execute; use crate::executor::{Executor, RefExecutor}; diff --git a/sqlx-core/src/query.rs b/sqlx-core/src/query.rs index c40adfab..756e84f9 100644 --- a/sqlx-core/src/query.rs +++ b/sqlx-core/src/query.rs @@ -6,10 +6,11 @@ use futures_util::future::ready; use futures_util::TryFutureExt; use crate::arguments::Arguments; -use crate::cursor::Cursor; -use crate::database::{Database, HasCursor, HasRow}; +use crate::cursor::{Cursor, HasCursor}; +use crate::database::Database; use crate::encode::Encode; use crate::executor::{Execute, Executor, RefExecutor}; +use crate::row::HasRow; use crate::types::Type; /// Raw SQL query with bind parameters. Returned by [`query`][crate::query::query]. diff --git a/sqlx-core/src/row.rs b/sqlx-core/src/row.rs index 4fc31328..5bf758a1 100644 --- a/sqlx-core/src/row.rs +++ b/sqlx-core/src/row.rs @@ -1,8 +1,9 @@ //! Contains the `ColumnIndex`, `Row`, and `FromRow` traits. -use crate::database::{Database, HasRawValue}; +use crate::database::Database; use crate::decode::Decode; use crate::types::Type; +use crate::value::HasRawValue; /// A type that can be used to index into a [`Row`]. /// @@ -149,6 +150,21 @@ pub(crate) mod private_row { pub trait Sealed {} } +/// Associate [`Database`] with a [`Row`] of a generic lifetime. +/// +/// --- +/// +/// The upcoming Rust feature, [Generic Associated Types], should obviate +/// the need for this trait. +/// +/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 +pub trait HasRow<'c> { + type Database: Database; + + /// The concrete `Row` implementation for this database. + type Row: Row<'c, Database = Self::Database>; +} + /// A record that can be built from a row returned by the database. /// /// In order to use [`query_as`] the output type must implement `FromRow`. @@ -292,38 +308,6 @@ macro_rules! impl_map_row_for_row { }; } -#[allow(unused_macros)] -macro_rules! impl_column_index_for_row { - ($R:ident) => { - impl<'c> crate::row::ColumnIndex<'c, $R<'c>> for usize { - fn index( - &self, - row: &$R<'c>, - ) -> crate::Result<<$R<'c> as crate::row::Row<'c>>::Database, usize> { - let len = crate::row::Row::len(row); - - if *self >= len { - return Err(crate::Error::ColumnIndexOutOfBounds { len, index: *self }); - } - - Ok(*self) - } - } - - impl<'c> crate::row::ColumnIndex<'c, $R<'c>> for str { - fn index( - &self, - row: &$R<'c>, - ) -> crate::Result<<$R<'c> as crate::row::Row<'c>>::Database, usize> { - row.columns - .get(self) - .ok_or_else(|| crate::Error::ColumnNotFound((*self).into())) - .map(|&index| index as usize) - } - } - }; -} - #[allow(unused_macros)] macro_rules! impl_from_row_for_row { ($R:ident) => { diff --git a/sqlx-core/src/transaction.rs b/sqlx-core/src/transaction.rs index 366cae1a..3f2790aa 100644 --- a/sqlx-core/src/transaction.rs +++ b/sqlx-core/src/transaction.rs @@ -3,8 +3,8 @@ use std::ops::{Deref, DerefMut}; use futures_core::future::BoxFuture; use crate::connection::Connection; +use crate::cursor::HasCursor; use crate::database::Database; -use crate::database::HasCursor; use crate::describe::Describe; use crate::executor::{Execute, Executor, RefExecutor}; use crate::runtime::spawn; diff --git a/sqlx-core/src/value.rs b/sqlx-core/src/value.rs new file mode 100644 index 00000000..b757d31b --- /dev/null +++ b/sqlx-core/src/value.rs @@ -0,0 +1,23 @@ +use crate::database::Database; + +/// Associate [`Database`] with a `RawValue` of a generic lifetime. +/// +/// --- +/// +/// The upcoming Rust feature, [Generic Associated Types], should obviate +/// the need for this trait. +/// +/// [Generic Associated Types]: https://www.google.com/search?q=generic+associated+types+rust&oq=generic+associated+types+rust&aqs=chrome..69i57j0l5.3327j0j7&sourceid=chrome&ie=UTF-8 +pub trait HasRawValue<'c> { + type Database: Database; + + /// The Rust type used to hold a not-yet-decoded value that has just been + /// received from the database. + type RawValue: RawValue<'c, Database = Self::Database>; +} + +pub trait RawValue<'c> { + type Database: Database; + + fn type_info(&self) -> ::TypeInfo; +}