mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 06:24:16 +00:00
Generic Associated Types in Database, replacing HasValueRef, HasArguments, HasStatement (#2973)
* HasValueRef, HasArguments, HasStatement -> Database GATs replace the associated types from the generic traits `HasValueRef<'r>`, `HasArguments<'q>` and `HasStatement<'q>` with generic associated types in `Database` * fixup after rebase --------- Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
This commit is contained in:
parent
936744dfd6
commit
9ba488c831
33 changed files with 173 additions and 284 deletions
|
@ -2,7 +2,7 @@ use crate::any::{
|
||||||
AnyArgumentBuffer, AnyArguments, AnyColumn, AnyConnection, AnyQueryResult, AnyRow,
|
AnyArgumentBuffer, AnyArguments, AnyColumn, AnyConnection, AnyQueryResult, AnyRow,
|
||||||
AnyStatement, AnyTransactionManager, AnyTypeInfo, AnyValue, AnyValueRef,
|
AnyStatement, AnyTransactionManager, AnyTypeInfo, AnyValue, AnyValueRef,
|
||||||
};
|
};
|
||||||
use crate::database::{Database, HasArguments, HasStatement, HasStatementCache, HasValueRef};
|
use crate::database::{Database, HasStatementCache};
|
||||||
|
|
||||||
/// Opaque database driver. Capable of being used in place of any SQLx database driver. The actual
|
/// Opaque database driver. Capable of being used in place of any SQLx database driver. The actual
|
||||||
/// driver used will be selected at runtime, from the connection url.
|
/// driver used will be selected at runtime, from the connection url.
|
||||||
|
@ -23,30 +23,17 @@ impl Database for Any {
|
||||||
type TypeInfo = AnyTypeInfo;
|
type TypeInfo = AnyTypeInfo;
|
||||||
|
|
||||||
type Value = AnyValue;
|
type Value = AnyValue;
|
||||||
|
type ValueRef<'r> = AnyValueRef<'r>;
|
||||||
|
|
||||||
|
type Arguments<'q> = AnyArguments<'q>;
|
||||||
|
type ArgumentBuffer<'q> = AnyArgumentBuffer<'q>;
|
||||||
|
|
||||||
|
type Statement<'q> = AnyStatement<'q>;
|
||||||
|
|
||||||
const NAME: &'static str = "Any";
|
const NAME: &'static str = "Any";
|
||||||
|
|
||||||
const URL_SCHEMES: &'static [&'static str] = &[];
|
const URL_SCHEMES: &'static [&'static str] = &[];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> HasValueRef<'r> for Any {
|
|
||||||
type Database = Any;
|
|
||||||
|
|
||||||
type ValueRef = AnyValueRef<'r>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasStatement<'q> for Any {
|
|
||||||
type Database = Any;
|
|
||||||
|
|
||||||
type Statement = AnyStatement<'q>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasArguments<'q> for Any {
|
|
||||||
type Database = Any;
|
|
||||||
|
|
||||||
type Arguments = AnyArguments<'q>;
|
|
||||||
|
|
||||||
type ArgumentBuffer = AnyArgumentBuffer<'q>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This _may_ be true, depending on the selected database
|
// This _may_ be true, depending on the selected database
|
||||||
impl HasStatementCache for Any {}
|
impl HasStatementCache for Any {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::any::error::mismatched_types;
|
use crate::any::error::mismatched_types;
|
||||||
use crate::any::{Any, AnyColumn, AnyTypeInfo, AnyTypeInfoKind, AnyValue, AnyValueKind};
|
use crate::any::{Any, AnyColumn, AnyTypeInfo, AnyTypeInfoKind, AnyValue, AnyValueKind};
|
||||||
use crate::column::{Column, ColumnIndex};
|
use crate::column::{Column, ColumnIndex};
|
||||||
use crate::database::{Database, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::ext::ustr::UStr;
|
use crate::ext::ustr::UStr;
|
||||||
|
@ -28,10 +28,7 @@ impl Row for AnyRow {
|
||||||
&self.columns
|
&self.columns
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_get_raw<I>(
|
fn try_get_raw<I>(&self, index: I) -> Result<<Self::Database as Database>::ValueRef<'_>, Error>
|
||||||
&self,
|
|
||||||
index: I,
|
|
||||||
) -> Result<<Self::Database as HasValueRef<'_>>::ValueRef, Error>
|
|
||||||
where
|
where
|
||||||
I: ColumnIndex<Self>,
|
I: ColumnIndex<Self>,
|
||||||
{
|
{
|
||||||
|
@ -141,7 +138,7 @@ impl AnyRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode<'r, DB: Database, T: Decode<'r, DB>>(
|
fn decode<'r, DB: Database, T: Decode<'r, DB>>(
|
||||||
valueref: <DB as HasValueRef<'r>>::ValueRef,
|
valueref: <DB as Database>::ValueRef<'r>,
|
||||||
) -> crate::Result<T> {
|
) -> crate::Result<T> {
|
||||||
Decode::decode(valueref).map_err(Error::decode)
|
Decode::decode(valueref).map_err(Error::decode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
||||||
use crate::database::{HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -15,14 +15,14 @@ impl Type<Any> for [u8] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for &'q [u8] {
|
impl<'q> Encode<'q, Any> for &'q [u8] {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Blob((*self).into()));
|
buf.0.push(AnyValueKind::Blob((*self).into()));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for &'r [u8] {
|
impl<'r> Decode<'r, Any> for &'r [u8] {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
AnyValueKind::Blob(Cow::Borrowed(blob)) => Ok(blob),
|
AnyValueKind::Blob(Cow::Borrowed(blob)) => Ok(blob),
|
||||||
// This shouldn't happen in practice, it means the user got an `AnyValueRef`
|
// This shouldn't happen in practice, it means the user got an `AnyValueRef`
|
||||||
|
@ -42,14 +42,14 @@ impl Type<Any> for Vec<u8> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for Vec<u8> {
|
impl<'q> Encode<'q, Any> for Vec<u8> {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Blob(Cow::Owned(self.clone())));
|
buf.0.push(AnyValueKind::Blob(Cow::Owned(self.clone())));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for Vec<u8> {
|
impl<'r> Decode<'r, Any> for Vec<u8> {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
AnyValueKind::Blob(blob) => Ok(blob.into_owned()),
|
AnyValueKind::Blob(blob) => Ok(blob.into_owned()),
|
||||||
other => other.unexpected(),
|
other => other.unexpected(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
||||||
use crate::database::{HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -14,14 +14,14 @@ impl Type<Any> for bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for bool {
|
impl<'q> Encode<'q, Any> for bool {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Bool(*self));
|
buf.0.push(AnyValueKind::Bool(*self));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for bool {
|
impl<'r> Decode<'r, Any> for bool {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
AnyValueKind::Bool(b) => Ok(b),
|
AnyValueKind::Bool(b) => Ok(b),
|
||||||
other => other.unexpected(),
|
other => other.unexpected(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::any::{Any, AnyArgumentBuffer, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind, AnyValueRef};
|
use crate::any::{Any, AnyArgumentBuffer, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind, AnyValueRef};
|
||||||
use crate::database::{HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -38,14 +38,14 @@ impl Type<Any> for f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for f64 {
|
impl<'q> Encode<'q, Any> for f64 {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Double(*self));
|
buf.0.push(AnyValueKind::Double(*self));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for f64 {
|
impl<'r> Decode<'r, Any> for f64 {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
// Widening is safe
|
// Widening is safe
|
||||||
AnyValueKind::Real(r) => Ok(r as f64),
|
AnyValueKind::Real(r) => Ok(r as f64),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
||||||
use crate::database::{HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -18,14 +18,14 @@ impl Type<Any> for i16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for i16 {
|
impl<'q> Encode<'q, Any> for i16 {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::SmallInt(*self));
|
buf.0.push(AnyValueKind::SmallInt(*self));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for i16 {
|
impl<'r> Decode<'r, Any> for i16 {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
value.kind.try_integer()
|
value.kind.try_integer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,14 @@ impl Type<Any> for i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for i32 {
|
impl<'q> Encode<'q, Any> for i32 {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Integer(*self));
|
buf.0.push(AnyValueKind::Integer(*self));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for i32 {
|
impl<'r> Decode<'r, Any> for i32 {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
value.kind.try_integer()
|
value.kind.try_integer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,14 @@ impl Type<Any> for i64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for i64 {
|
impl<'q> Encode<'q, Any> for i64 {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::BigInt(*self));
|
buf.0.push(AnyValueKind::BigInt(*self));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for i64 {
|
impl<'r> Decode<'r, Any> for i64 {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
value.kind.try_integer()
|
value.kind.try_integer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::any::types::str;
|
use crate::any::types::str;
|
||||||
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
|
||||||
use crate::database::{HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -16,7 +16,7 @@ impl Type<Any> for str {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Encode<'a, Any> for &'a str {
|
impl<'a> Encode<'a, Any> for &'a str {
|
||||||
fn encode(self, buf: &mut <Any as HasArguments<'a>>::ArgumentBuffer) -> IsNull
|
fn encode(self, buf: &mut <Any as Database>::ArgumentBuffer<'a>) -> IsNull
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -24,13 +24,13 @@ impl<'a> Encode<'a, Any> for &'a str {
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'a>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'a>) -> IsNull {
|
||||||
(*self).encode(buf)
|
(*self).encode(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Decode<'a, Any> for &'a str {
|
impl<'a> Decode<'a, Any> for &'a str {
|
||||||
fn decode(value: <Any as HasValueRef<'a>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'a>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
AnyValueKind::Text(Cow::Borrowed(text)) => Ok(text),
|
AnyValueKind::Text(Cow::Borrowed(text)) => Ok(text),
|
||||||
// This shouldn't happen in practice, it means the user got an `AnyValueRef`
|
// This shouldn't happen in practice, it means the user got an `AnyValueRef`
|
||||||
|
@ -50,14 +50,14 @@ impl Type<Any> for String {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Encode<'q, Any> for String {
|
impl<'q> Encode<'q, Any> for String {
|
||||||
fn encode_by_ref(&self, buf: &mut <Any as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <Any as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
buf.0.push(AnyValueKind::Text(Cow::Owned(self.clone())));
|
buf.0.push(AnyValueKind::Text(Cow::Owned(self.clone())));
|
||||||
IsNull::No
|
IsNull::No
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Decode<'r, Any> for String {
|
impl<'r> Decode<'r, Any> for String {
|
||||||
fn decode(value: <Any as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
match value.kind {
|
match value.kind {
|
||||||
AnyValueKind::Text(text) => Ok(text.into_owned()),
|
AnyValueKind::Text(text) => Ok(text.into_owned()),
|
||||||
other => other.unexpected(),
|
other => other.unexpected(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind};
|
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind};
|
||||||
use crate::database::{Database, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
use crate::types::Type;
|
use crate::types::Type;
|
||||||
use crate::value::{Value, ValueRef};
|
use crate::value::{Value, ValueRef};
|
||||||
|
@ -71,7 +71,7 @@ pub struct AnyValueRef<'a> {
|
||||||
impl Value for AnyValue {
|
impl Value for AnyValue {
|
||||||
type Database = Any;
|
type Database = Any;
|
||||||
|
|
||||||
fn as_ref(&self) -> <Self::Database as HasValueRef<'_>>::ValueRef {
|
fn as_ref(&self) -> <Self::Database as Database>::ValueRef<'_> {
|
||||||
AnyValueRef {
|
AnyValueRef {
|
||||||
kind: match &self.kind {
|
kind: match &self.kind {
|
||||||
AnyValueKind::Null => AnyValueKind::Null,
|
AnyValueKind::Null => AnyValueKind::Null,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Types and traits for passing arguments to SQL queries.
|
//! Types and traits for passing arguments to SQL queries.
|
||||||
|
|
||||||
use crate::database::{Database, HasArguments};
|
use crate::database::Database;
|
||||||
use crate::encode::Encode;
|
use crate::encode::Encode;
|
||||||
use crate::types::Type;
|
use crate::types::Type;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -23,8 +23,8 @@ pub trait Arguments<'q>: Send + Sized + Default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IntoArguments<'q, DB: HasArguments<'q>>: Sized + Send {
|
pub trait IntoArguments<'q, DB: Database>: Sized + Send {
|
||||||
fn into_arguments(self) -> <DB as HasArguments<'q>>::Arguments;
|
fn into_arguments(self) -> <DB as Database>::Arguments<'q>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: required due to lack of lazy normalization
|
// NOTE: required due to lack of lazy normalization
|
||||||
|
@ -45,10 +45,10 @@ macro_rules! impl_into_arguments_for_arguments {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// used by the query macros to prevent supernumerary `.bind()` calls
|
/// used by the query macros to prevent supernumerary `.bind()` calls
|
||||||
pub struct ImmutableArguments<'q, DB: HasArguments<'q>>(pub <DB as HasArguments<'q>>::Arguments);
|
pub struct ImmutableArguments<'q, DB: Database>(pub <DB as Database>::Arguments<'q>);
|
||||||
|
|
||||||
impl<'q, DB: HasArguments<'q>> IntoArguments<'q, DB> for ImmutableArguments<'q, DB> {
|
impl<'q, DB: Database> IntoArguments<'q, DB> for ImmutableArguments<'q, DB> {
|
||||||
fn into_arguments(self) -> <DB as HasArguments<'q>>::Arguments {
|
fn into_arguments(self) -> <DB as Database>::Arguments<'q> {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,15 +69,7 @@ use crate::value::{Value, ValueRef};
|
||||||
///
|
///
|
||||||
/// This trait encapsulates a complete set of traits that implement a driver for a
|
/// This trait encapsulates a complete set of traits that implement a driver for a
|
||||||
/// specific database (e.g., MySQL, PostgreSQL).
|
/// specific database (e.g., MySQL, PostgreSQL).
|
||||||
pub trait Database:
|
pub trait Database: 'static + Sized + Send + Debug {
|
||||||
'static
|
|
||||||
+ Sized
|
|
||||||
+ Send
|
|
||||||
+ Debug
|
|
||||||
+ for<'r> HasValueRef<'r, Database = Self>
|
|
||||||
+ for<'q> HasArguments<'q, Database = Self>
|
|
||||||
+ for<'q> HasStatement<'q, Database = Self>
|
|
||||||
{
|
|
||||||
/// The concrete `Connection` implementation for this database.
|
/// The concrete `Connection` implementation for this database.
|
||||||
type Connection: Connection<Database = Self>;
|
type Connection: Connection<Database = Self>;
|
||||||
|
|
||||||
|
@ -99,6 +91,17 @@ pub trait Database:
|
||||||
/// The concrete type used to hold an owned copy of the not-yet-decoded value that was
|
/// The concrete type used to hold an owned copy of the not-yet-decoded value that was
|
||||||
/// received from the database.
|
/// received from the database.
|
||||||
type Value: Value<Database = Self> + 'static;
|
type Value: Value<Database = Self> + 'static;
|
||||||
|
/// The concrete type used to hold a reference to the not-yet-decoded value that has just been
|
||||||
|
/// received from the database.
|
||||||
|
type ValueRef<'r>: ValueRef<'r, Database = Self>;
|
||||||
|
|
||||||
|
/// The concrete `Arguments` implementation for this database.
|
||||||
|
type Arguments<'q>: Arguments<'q, Database = Self>;
|
||||||
|
/// The concrete type used as a buffer for arguments while encoding.
|
||||||
|
type ArgumentBuffer<'q>;
|
||||||
|
|
||||||
|
/// The concrete `Statement` implementation for this database.
|
||||||
|
type Statement<'q>: Statement<'q, Database = Self>;
|
||||||
|
|
||||||
/// The display name for this database driver.
|
/// The display name for this database driver.
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
@ -107,54 +110,5 @@ pub trait Database:
|
||||||
const URL_SCHEMES: &'static [&'static str];
|
const URL_SCHEMES: &'static [&'static str];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Associate [`Database`] with a [`ValueRef`](crate::value::ValueRef) of a generic lifetime.
|
|
||||||
///
|
|
||||||
/// ---
|
|
||||||
///
|
|
||||||
/// The upcoming Rust feature, [Generic Associated Types], should obviate
|
|
||||||
/// the need for this trait.
|
|
||||||
///
|
|
||||||
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
|
|
||||||
pub trait HasValueRef<'r> {
|
|
||||||
type Database: Database;
|
|
||||||
|
|
||||||
/// The concrete type used to hold a reference to the not-yet-decoded value that has just been
|
|
||||||
/// received from the database.
|
|
||||||
type ValueRef: ValueRef<'r, Database = Self::Database>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Associate [`Database`] with an [`Arguments`](crate::arguments::Arguments) of a generic lifetime.
|
|
||||||
///
|
|
||||||
/// ---
|
|
||||||
///
|
|
||||||
/// The upcoming Rust feature, [Generic Associated Types], should obviate
|
|
||||||
/// the need for this trait.
|
|
||||||
///
|
|
||||||
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
|
|
||||||
pub trait HasArguments<'q> {
|
|
||||||
type Database: Database;
|
|
||||||
|
|
||||||
/// The concrete `Arguments` implementation for this database.
|
|
||||||
type Arguments: Arguments<'q, Database = Self::Database>;
|
|
||||||
|
|
||||||
/// The concrete type used as a buffer for arguments while encoding.
|
|
||||||
type ArgumentBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Associate [`Database`] with a [`Statement`](crate::statement::Statement) of a generic lifetime.
|
|
||||||
///
|
|
||||||
/// ---
|
|
||||||
///
|
|
||||||
/// The upcoming Rust feature, [Generic Associated Types], should obviate
|
|
||||||
/// the need for this trait.
|
|
||||||
///
|
|
||||||
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
|
|
||||||
pub trait HasStatement<'q> {
|
|
||||||
type Database: Database;
|
|
||||||
|
|
||||||
/// The concrete `Statement` implementation for this database.
|
|
||||||
type Statement: Statement<'q, Database = Self::Database>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A [`Database`] that maintains a client-side cache of prepared statements.
|
/// A [`Database`] that maintains a client-side cache of prepared statements.
|
||||||
pub trait HasStatementCache {}
|
pub trait HasStatementCache {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Provides [`Decode`] for decoding values from the database.
|
//! Provides [`Decode`] for decoding values from the database.
|
||||||
|
|
||||||
use crate::database::{Database, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
|
||||||
use crate::value::ValueRef;
|
use crate::value::ValueRef;
|
||||||
|
@ -14,10 +14,10 @@ use crate::value::ValueRef;
|
||||||
///
|
///
|
||||||
/// The following showcases how to implement `Decode` to be generic over [`Database`]. The
|
/// The following showcases how to implement `Decode` to be generic over [`Database`]. The
|
||||||
/// implementation can be marginally simpler if you remove the `DB` type parameter and explicitly
|
/// implementation can be marginally simpler if you remove the `DB` type parameter and explicitly
|
||||||
/// use the concrete [`ValueRef`](HasValueRef::ValueRef) and [`TypeInfo`](Database::TypeInfo) types.
|
/// use the concrete [`ValueRef`](Database::ValueRef) and [`TypeInfo`](Database::TypeInfo) types.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use sqlx_core::database::{Database, HasValueRef};
|
/// # use sqlx_core::database::{Database};
|
||||||
/// # use sqlx_core::decode::Decode;
|
/// # use sqlx_core::decode::Decode;
|
||||||
/// # use sqlx_core::types::Type;
|
/// # use sqlx_core::types::Type;
|
||||||
/// # use std::error::Error;
|
/// # use std::error::Error;
|
||||||
|
@ -42,7 +42,7 @@ use crate::value::ValueRef;
|
||||||
/// &'r str: Decode<'r, DB>
|
/// &'r str: Decode<'r, DB>
|
||||||
/// {
|
/// {
|
||||||
/// fn decode(
|
/// fn decode(
|
||||||
/// value: <DB as HasValueRef<'r>>::ValueRef,
|
/// value: <DB as Database>::ValueRef<'r>,
|
||||||
/// ) -> Result<MyType, Box<dyn Error + 'static + Send + Sync>> {
|
/// ) -> Result<MyType, Box<dyn Error + 'static + Send + Sync>> {
|
||||||
/// // the interface of ValueRef is largely unstable at the moment
|
/// // the interface of ValueRef is largely unstable at the moment
|
||||||
/// // so this is not directly implementable
|
/// // so this is not directly implementable
|
||||||
|
@ -60,7 +60,7 @@ use crate::value::ValueRef;
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Decode<'r, DB: Database>: Sized {
|
pub trait Decode<'r, DB: Database>: Sized {
|
||||||
/// Decode a new value of this type using a raw value from the database.
|
/// Decode a new value of this type using a raw value from the database.
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError>;
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// implement `Decode` for Option<T> for all SQL types
|
// implement `Decode` for Option<T> for all SQL types
|
||||||
|
@ -69,7 +69,7 @@ where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
T: Decode<'r, DB>,
|
T: Decode<'r, DB>,
|
||||||
{
|
{
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
if value.is_null() {
|
if value.is_null() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use crate::database::{Database, HasArguments};
|
use crate::database::Database;
|
||||||
|
|
||||||
/// The return type of [Encode::encode].
|
/// The return type of [Encode::encode].
|
||||||
pub enum IsNull {
|
pub enum IsNull {
|
||||||
|
@ -19,7 +19,7 @@ pub enum IsNull {
|
||||||
pub trait Encode<'q, DB: Database> {
|
pub trait Encode<'q, DB: Database> {
|
||||||
/// Writes the value of `self` into `buf` in the expected format for the database.
|
/// Writes the value of `self` into `buf` in the expected format for the database.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn encode(self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull
|
fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ pub trait Encode<'q, DB: Database> {
|
||||||
/// Where possible, make use of `encode` instead as it can take advantage of re-using
|
/// Where possible, make use of `encode` instead as it can take advantage of re-using
|
||||||
/// memory.
|
/// memory.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull;
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull;
|
||||||
|
|
||||||
fn produces(&self) -> Option<DB::TypeInfo> {
|
fn produces(&self) -> Option<DB::TypeInfo> {
|
||||||
// `produces` is inherently a hook to allow database drivers to produce value-dependent
|
// `produces` is inherently a hook to allow database drivers to produce value-dependent
|
||||||
|
@ -50,12 +50,12 @@ where
|
||||||
T: Encode<'q, DB>,
|
T: Encode<'q, DB>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode(self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
<T as Encode<DB>>::encode_by_ref(self, buf)
|
<T as Encode<DB>>::encode_by_ref(self, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
<&T as Encode<DB>>::encode(self, buf)
|
<&T as Encode<DB>>::encode(self, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ macro_rules! impl_encode_for_option {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode(
|
fn encode(
|
||||||
self,
|
self,
|
||||||
buf: &mut <$DB as $crate::database::HasArguments<'q>>::ArgumentBuffer,
|
buf: &mut <$DB as $crate::database::Database>::ArgumentBuffer<'q>,
|
||||||
) -> $crate::encode::IsNull {
|
) -> $crate::encode::IsNull {
|
||||||
if let Some(v) = self {
|
if let Some(v) = self {
|
||||||
v.encode(buf)
|
v.encode(buf)
|
||||||
|
@ -101,7 +101,7 @@ macro_rules! impl_encode_for_option {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode_by_ref(
|
fn encode_by_ref(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut <$DB as $crate::database::HasArguments<'q>>::ArgumentBuffer,
|
buf: &mut <$DB as $crate::database::Database>::ArgumentBuffer<'q>,
|
||||||
) -> $crate::encode::IsNull {
|
) -> $crate::encode::IsNull {
|
||||||
if let Some(v) = self {
|
if let Some(v) = self {
|
||||||
v.encode_by_ref(buf)
|
v.encode_by_ref(buf)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{Database, HasArguments, HasStatement};
|
use crate::database::Database;
|
||||||
use crate::describe::Describe;
|
use crate::describe::Describe;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
||||||
fn prepare<'e, 'q: 'e>(
|
fn prepare<'e, 'q: 'e>(
|
||||||
self,
|
self,
|
||||||
query: &'q str,
|
query: &'q str,
|
||||||
) -> BoxFuture<'e, Result<<Self::Database as HasStatement<'q>>::Statement, Error>>
|
) -> BoxFuture<'e, Result<<Self::Database as Database>::Statement<'q>, Error>>
|
||||||
where
|
where
|
||||||
'c: 'e,
|
'c: 'e,
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ pub trait Executor<'c>: Send + Debug + Sized {
|
||||||
self,
|
self,
|
||||||
sql: &'q str,
|
sql: &'q str,
|
||||||
parameters: &'e [<Self::Database as Database>::TypeInfo],
|
parameters: &'e [<Self::Database as Database>::TypeInfo],
|
||||||
) -> BoxFuture<'e, Result<<Self::Database as HasStatement<'q>>::Statement, Error>>
|
) -> BoxFuture<'e, Result<<Self::Database as Database>::Statement<'q>, Error>>
|
||||||
where
|
where
|
||||||
'c: 'e;
|
'c: 'e;
|
||||||
|
|
||||||
|
@ -195,14 +195,14 @@ pub trait Execute<'q, DB: Database>: Send + Sized {
|
||||||
fn sql(&self) -> &'q str;
|
fn sql(&self) -> &'q str;
|
||||||
|
|
||||||
/// Gets the previously cached statement, if available.
|
/// Gets the previously cached statement, if available.
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement>;
|
fn statement(&self) -> Option<&DB::Statement<'q>>;
|
||||||
|
|
||||||
/// Returns the arguments to be bound against the query string.
|
/// Returns the arguments to be bound against the query string.
|
||||||
///
|
///
|
||||||
/// Returning `None` for `Arguments` indicates to use a "simple" query protocol and to not
|
/// Returning `None` for `Arguments` indicates to use a "simple" query protocol and to not
|
||||||
/// prepare the query. Returning `Some(Default::default())` is an empty arguments object that
|
/// prepare the query. Returning `Some(Default::default())` is an empty arguments object that
|
||||||
/// will be prepared (and cached) before execution.
|
/// will be prepared (and cached) before execution.
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments>;
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>>;
|
||||||
|
|
||||||
/// Returns `true` if the statement should be cached.
|
/// Returns `true` if the statement should be cached.
|
||||||
fn persistent(&self) -> bool;
|
fn persistent(&self) -> bool;
|
||||||
|
@ -217,12 +217,12 @@ impl<'q, DB: Database> Execute<'q, DB> for &'q str {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,19 +232,19 @@ impl<'q, DB: Database> Execute<'q, DB> for &'q str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q, DB: Database> Execute<'q, DB> for (&'q str, Option<<DB as HasArguments<'q>>::Arguments>) {
|
impl<'q, DB: Database> Execute<'q, DB> for (&'q str, Option<<DB as Database>::Arguments<'q>>) {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sql(&self) -> &'q str {
|
fn sql(&self) -> &'q str {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
self.1.take()
|
self.1.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use futures_core::future::BoxFuture;
|
||||||
use futures_core::stream::BoxStream;
|
use futures_core::stream::BoxStream;
|
||||||
use futures_util::TryStreamExt;
|
use futures_util::TryStreamExt;
|
||||||
|
|
||||||
use crate::database::{Database, HasStatement};
|
use crate::database::Database;
|
||||||
use crate::describe::Describe;
|
use crate::describe::Describe;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::executor::{Execute, Executor};
|
use crate::executor::{Execute, Executor};
|
||||||
|
@ -52,7 +52,7 @@ where
|
||||||
self,
|
self,
|
||||||
sql: &'q str,
|
sql: &'q str,
|
||||||
parameters: &'e [<Self::Database as Database>::TypeInfo],
|
parameters: &'e [<Self::Database as Database>::TypeInfo],
|
||||||
) -> BoxFuture<'e, Result<<Self::Database as HasStatement<'q>>::Statement, Error>> {
|
) -> BoxFuture<'e, Result<<Self::Database as Database>::Statement<'q>, Error>> {
|
||||||
let pool = self.clone();
|
let pool = self.clone();
|
||||||
|
|
||||||
Box::pin(async move { pool.acquire().await?.prepare_with(sql, parameters).await })
|
Box::pin(async move { pool.acquire().await?.prepare_with(sql, parameters).await })
|
||||||
|
@ -117,7 +117,7 @@ where
|
||||||
// parameters: &'e [<DB as crate::database::Database>::TypeInfo],
|
// parameters: &'e [<DB as crate::database::Database>::TypeInfo],
|
||||||
// ) -> futures_core::future::BoxFuture<
|
// ) -> futures_core::future::BoxFuture<
|
||||||
// 'e,
|
// 'e,
|
||||||
// Result<<DB as crate::database::HasStatement<'q>>::Statement, crate::error::Error>,
|
// Result<<DB as crate::database::Database>::Statement<'q>, crate::error::Error>,
|
||||||
// >
|
// >
|
||||||
// where
|
// where
|
||||||
// 'c: 'e,
|
// 'c: 'e,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use futures_core::stream::BoxStream;
|
||||||
use futures_util::{future, StreamExt, TryFutureExt, TryStreamExt};
|
use futures_util::{future, StreamExt, TryFutureExt, TryStreamExt};
|
||||||
|
|
||||||
use crate::arguments::{Arguments, IntoArguments};
|
use crate::arguments::{Arguments, IntoArguments};
|
||||||
use crate::database::{Database, HasArguments, HasStatement, HasStatementCache};
|
use crate::database::{Database, HasStatementCache};
|
||||||
use crate::encode::Encode;
|
use crate::encode::Encode;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::executor::{Execute, Executor};
|
use crate::executor::{Execute, Executor};
|
||||||
|
@ -15,7 +15,7 @@ use crate::types::Type;
|
||||||
/// A single SQL query as a prepared statement. Returned by [`query()`].
|
/// A single SQL query as a prepared statement. Returned by [`query()`].
|
||||||
#[must_use = "query must be executed to affect database"]
|
#[must_use = "query must be executed to affect database"]
|
||||||
pub struct Query<'q, DB: Database, A> {
|
pub struct Query<'q, DB: Database, A> {
|
||||||
pub(crate) statement: Either<&'q str, &'q <DB as HasStatement<'q>>::Statement>,
|
pub(crate) statement: Either<&'q str, &'q DB::Statement<'q>>,
|
||||||
pub(crate) arguments: Option<A>,
|
pub(crate) arguments: Option<A>,
|
||||||
pub(crate) database: PhantomData<DB>,
|
pub(crate) database: PhantomData<DB>,
|
||||||
pub(crate) persistent: bool,
|
pub(crate) persistent: bool,
|
||||||
|
@ -51,7 +51,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
match self.statement {
|
match self.statement {
|
||||||
Either::Right(ref statement) => Some(&statement),
|
Either::Right(ref statement) => Some(&statement),
|
||||||
Either::Left(_) => None,
|
Either::Left(_) => None,
|
||||||
|
@ -59,7 +59,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
self.arguments.take().map(IntoArguments::into_arguments)
|
self.arguments.take().map(IntoArguments::into_arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q, DB: Database> Query<'q, DB, <DB as HasArguments<'q>>::Arguments> {
|
impl<'q, DB: Database> Query<'q, DB, <DB as Database>::Arguments<'q>> {
|
||||||
/// Bind a value for use with this SQL query.
|
/// Bind a value for use with this SQL query.
|
||||||
///
|
///
|
||||||
/// If the number of times this is called does not match the number of bind parameters that
|
/// If the number of times this is called does not match the number of bind parameters that
|
||||||
|
@ -275,12 +275,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
self.inner.statement()
|
self.inner.statement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
self.inner.take_arguments()
|
self.inner.take_arguments()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,8 +465,8 @@ where
|
||||||
|
|
||||||
/// Execute a single SQL query as a prepared statement (explicitly created).
|
/// Execute a single SQL query as a prepared statement (explicitly created).
|
||||||
pub fn query_statement<'q, DB>(
|
pub fn query_statement<'q, DB>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
) -> Query<'q, DB, <DB as HasArguments<'_>>::Arguments>
|
) -> Query<'q, DB, <DB as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
|
@ -480,7 +480,7 @@ where
|
||||||
|
|
||||||
/// Execute a single SQL query as a prepared statement (explicitly created), with the given arguments.
|
/// Execute a single SQL query as a prepared statement (explicitly created), with the given arguments.
|
||||||
pub fn query_statement_with<'q, DB, A>(
|
pub fn query_statement_with<'q, DB, A>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
arguments: A,
|
arguments: A,
|
||||||
) -> Query<'q, DB, A>
|
) -> Query<'q, DB, A>
|
||||||
where
|
where
|
||||||
|
@ -525,6 +525,7 @@ where
|
||||||
/// // where `conn` is `PgConnection` or `MySqlConnection`
|
/// // where `conn` is `PgConnection` or `MySqlConnection`
|
||||||
/// // or some other type that implements `Executor`.
|
/// // or some other type that implements `Executor`.
|
||||||
/// let results = sqlx::query(&query).fetch_all(&mut conn).await?;
|
/// let results = sqlx::query(&query).fetch_all(&mut conn).await?;
|
||||||
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -618,7 +619,7 @@ where
|
||||||
///
|
///
|
||||||
/// As an additional benefit, query parameters are usually sent in a compact binary encoding instead of a human-readable
|
/// As an additional benefit, query parameters are usually sent in a compact binary encoding instead of a human-readable
|
||||||
/// text encoding, which saves bandwidth.
|
/// text encoding, which saves bandwidth.
|
||||||
pub fn query<DB>(sql: &str) -> Query<'_, DB, <DB as HasArguments<'_>>::Arguments>
|
pub fn query<DB>(sql: &str) -> Query<'_, DB, <DB as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ use futures_core::stream::BoxStream;
|
||||||
use futures_util::{StreamExt, TryStreamExt};
|
use futures_util::{StreamExt, TryStreamExt};
|
||||||
|
|
||||||
use crate::arguments::IntoArguments;
|
use crate::arguments::IntoArguments;
|
||||||
use crate::database::{Database, HasArguments, HasStatement, HasStatementCache};
|
use crate::database::{Database, HasStatementCache};
|
||||||
use crate::encode::Encode;
|
use crate::encode::Encode;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::executor::{Execute, Executor};
|
use crate::executor::{Execute, Executor};
|
||||||
|
@ -32,12 +32,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
self.inner.statement()
|
self.inner.statement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
self.inner.take_arguments()
|
self.inner.take_arguments()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q, DB: Database, O> QueryAs<'q, DB, O, <DB as HasArguments<'q>>::Arguments> {
|
impl<'q, DB: Database, O> QueryAs<'q, DB, O, <DB as Database>::Arguments<'q>> {
|
||||||
/// Bind a value for use with this SQL query.
|
/// Bind a value for use with this SQL query.
|
||||||
///
|
///
|
||||||
/// See [`Query::bind`](Query::bind).
|
/// See [`Query::bind`](Query::bind).
|
||||||
|
@ -339,7 +339,7 @@ where
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn query_as<'q, DB, O>(sql: &'q str) -> QueryAs<'q, DB, O, <DB as HasArguments<'q>>::Arguments>
|
pub fn query_as<'q, DB, O>(sql: &'q str) -> QueryAs<'q, DB, O, <DB as Database>::Arguments<'q>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
O: for<'r> FromRow<'r, DB::Row>,
|
O: for<'r> FromRow<'r, DB::Row>,
|
||||||
|
@ -371,8 +371,8 @@ where
|
||||||
|
|
||||||
// Make a SQL query from a statement, that is mapped to a concrete type.
|
// Make a SQL query from a statement, that is mapped to a concrete type.
|
||||||
pub fn query_statement_as<'q, DB, O>(
|
pub fn query_statement_as<'q, DB, O>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
) -> QueryAs<'q, DB, O, <DB as HasArguments<'_>>::Arguments>
|
) -> QueryAs<'q, DB, O, <DB as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
O: for<'r> FromRow<'r, DB::Row>,
|
O: for<'r> FromRow<'r, DB::Row>,
|
||||||
|
@ -385,7 +385,7 @@ where
|
||||||
|
|
||||||
// Make a SQL query from a statement, with the given arguments, that is mapped to a concrete type.
|
// Make a SQL query from a statement, with the given arguments, that is mapped to a concrete type.
|
||||||
pub fn query_statement_as_with<'q, DB, O, A>(
|
pub fn query_statement_as_with<'q, DB, O, A>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
arguments: A,
|
arguments: A,
|
||||||
) -> QueryAs<'q, DB, O, A>
|
) -> QueryAs<'q, DB, O, A>
|
||||||
where
|
where
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::fmt::Write;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use crate::arguments::{Arguments, IntoArguments};
|
use crate::arguments::{Arguments, IntoArguments};
|
||||||
use crate::database::{Database, HasArguments};
|
use crate::database::Database;
|
||||||
use crate::encode::Encode;
|
use crate::encode::Encode;
|
||||||
use crate::from_row::FromRow;
|
use crate::from_row::FromRow;
|
||||||
use crate::query::Query;
|
use crate::query::Query;
|
||||||
|
@ -27,7 +27,7 @@ where
|
||||||
{
|
{
|
||||||
query: String,
|
query: String,
|
||||||
init_len: usize,
|
init_len: usize,
|
||||||
arguments: Option<<DB as HasArguments<'args>>::Arguments>,
|
arguments: Option<<DB as Database>::Arguments<'args>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'args, DB: Database> Default for QueryBuilder<'args, DB> {
|
impl<'args, DB: Database> Default for QueryBuilder<'args, DB> {
|
||||||
|
@ -49,7 +49,7 @@ where
|
||||||
/// Start building a query with an initial SQL fragment, which may be an empty string.
|
/// Start building a query with an initial SQL fragment, which may be an empty string.
|
||||||
pub fn new(init: impl Into<String>) -> Self
|
pub fn new(init: impl Into<String>) -> Self
|
||||||
where
|
where
|
||||||
<DB as HasArguments<'args>>::Arguments: Default,
|
<DB as Database>::Arguments<'args>: Default,
|
||||||
{
|
{
|
||||||
let init = init.into();
|
let init = init.into();
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ where
|
||||||
/// to the state it was in immediately after [`new()`][Self::new].
|
/// to the state it was in immediately after [`new()`][Self::new].
|
||||||
///
|
///
|
||||||
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
||||||
pub fn build(&mut self) -> Query<'_, DB, <DB as HasArguments<'args>>::Arguments> {
|
pub fn build(&mut self) -> Query<'_, DB, <DB as Database>::Arguments<'args>> {
|
||||||
self.sanity_check();
|
self.sanity_check();
|
||||||
|
|
||||||
Query {
|
Query {
|
||||||
|
@ -470,7 +470,7 @@ where
|
||||||
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
||||||
pub fn build_query_as<'q, T: FromRow<'q, DB::Row>>(
|
pub fn build_query_as<'q, T: FromRow<'q, DB::Row>>(
|
||||||
&'q mut self,
|
&'q mut self,
|
||||||
) -> QueryAs<'q, DB, T, <DB as HasArguments<'args>>::Arguments> {
|
) -> QueryAs<'q, DB, T, <DB as Database>::Arguments<'args>> {
|
||||||
QueryAs {
|
QueryAs {
|
||||||
inner: self.build(),
|
inner: self.build(),
|
||||||
output: PhantomData,
|
output: PhantomData,
|
||||||
|
@ -491,7 +491,7 @@ where
|
||||||
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
/// Calling any other method but `.reset()` after `.build()` will panic for sanity reasons.
|
||||||
pub fn build_query_scalar<'q, T>(
|
pub fn build_query_scalar<'q, T>(
|
||||||
&'q mut self,
|
&'q mut self,
|
||||||
) -> QueryScalar<'q, DB, T, <DB as HasArguments<'args>>::Arguments>
|
) -> QueryScalar<'q, DB, T, <DB as Database>::Arguments<'args>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
(T,): for<'r> FromRow<'r, DB::Row>,
|
(T,): for<'r> FromRow<'r, DB::Row>,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use futures_core::stream::BoxStream;
|
||||||
use futures_util::{StreamExt, TryFutureExt, TryStreamExt};
|
use futures_util::{StreamExt, TryFutureExt, TryStreamExt};
|
||||||
|
|
||||||
use crate::arguments::IntoArguments;
|
use crate::arguments::IntoArguments;
|
||||||
use crate::database::{Database, HasArguments, HasStatement, HasStatementCache};
|
use crate::database::{Database, HasStatementCache};
|
||||||
use crate::encode::Encode;
|
use crate::encode::Encode;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::executor::{Execute, Executor};
|
use crate::executor::{Execute, Executor};
|
||||||
|
@ -29,12 +29,12 @@ where
|
||||||
self.inner.sql()
|
self.inner.sql()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&DB::Statement<'q>> {
|
||||||
self.inner.statement()
|
self.inner.statement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
self.inner.take_arguments()
|
self.inner.take_arguments()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q, DB: Database, O> QueryScalar<'q, DB, O, <DB as HasArguments<'q>>::Arguments> {
|
impl<'q, DB: Database, O> QueryScalar<'q, DB, O, <DB as Database>::Arguments<'q>> {
|
||||||
/// Bind a value for use with this SQL query.
|
/// Bind a value for use with this SQL query.
|
||||||
///
|
///
|
||||||
/// See [`Query::bind`](crate::query::Query::bind).
|
/// See [`Query::bind`](crate::query::Query::bind).
|
||||||
|
@ -320,7 +320,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn query_scalar<'q, DB, O>(
|
pub fn query_scalar<'q, DB, O>(
|
||||||
sql: &'q str,
|
sql: &'q str,
|
||||||
) -> QueryScalar<'q, DB, O, <DB as HasArguments<'q>>::Arguments>
|
) -> QueryScalar<'q, DB, O, <DB as Database>::Arguments<'q>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
(O,): for<'r> FromRow<'r, DB::Row>,
|
(O,): for<'r> FromRow<'r, DB::Row>,
|
||||||
|
@ -350,8 +350,8 @@ where
|
||||||
|
|
||||||
// Make a SQL query from a statement, that is mapped to a concrete value.
|
// Make a SQL query from a statement, that is mapped to a concrete value.
|
||||||
pub fn query_statement_scalar<'q, DB, O>(
|
pub fn query_statement_scalar<'q, DB, O>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
) -> QueryScalar<'q, DB, O, <DB as HasArguments<'_>>::Arguments>
|
) -> QueryScalar<'q, DB, O, <DB as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
(O,): for<'r> FromRow<'r, DB::Row>,
|
(O,): for<'r> FromRow<'r, DB::Row>,
|
||||||
|
@ -363,7 +363,7 @@ where
|
||||||
|
|
||||||
// Make a SQL query from a statement, with the given arguments, that is mapped to a concrete value.
|
// Make a SQL query from a statement, with the given arguments, that is mapped to a concrete value.
|
||||||
pub fn query_statement_scalar_with<'q, DB, O, A>(
|
pub fn query_statement_scalar_with<'q, DB, O, A>(
|
||||||
statement: &'q <DB as HasStatement<'q>>::Statement,
|
statement: &'q DB::Statement<'q>,
|
||||||
arguments: A,
|
arguments: A,
|
||||||
) -> QueryScalar<'q, DB, O, A>
|
) -> QueryScalar<'q, DB, O, A>
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::database::{Database, HasArguments, HasStatement};
|
|
||||||
use crate::executor::{Execute, Executor};
|
|
||||||
use crate::Error;
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use futures_core::stream::BoxStream;
|
use futures_core::stream::BoxStream;
|
||||||
|
|
||||||
|
use crate::database::Database;
|
||||||
|
use crate::executor::{Execute, Executor};
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
// AUTHOR'S NOTE: I was just going to call this API `sql()` and `Sql`, respectively,
|
// AUTHOR'S NOTE: I was just going to call this API `sql()` and `Sql`, respectively,
|
||||||
// but realized that would be extremely annoying to deal with as a SQLite user
|
// but realized that would be extremely annoying to deal with as a SQLite user
|
||||||
// because IDE smart completion would always recommend the `Sql` type first.
|
// because IDE smart completion would always recommend the `Sql` type first.
|
||||||
|
@ -121,11 +122,11 @@ impl<'q, DB: Database> Execute<'q, DB> for RawSql<'q> {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&self) -> Option<&<DB as HasStatement<'q>>::Statement> {
|
fn statement(&self) -> Option<&<DB as Database>::Statement<'q>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_arguments(&mut self) -> Option<<DB as HasArguments<'q>>::Arguments> {
|
fn take_arguments(&mut self) -> Option<<DB as Database>::Arguments<'q>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::column::ColumnIndex;
|
use crate::column::ColumnIndex;
|
||||||
use crate::database::{Database, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::error::{mismatched_types, Error};
|
use crate::error::{mismatched_types, Error};
|
||||||
|
|
||||||
|
@ -171,10 +171,7 @@ pub trait Row: Unpin + Send + Sync + 'static {
|
||||||
/// [`ColumnNotFound`]: Error::ColumnNotFound
|
/// [`ColumnNotFound`]: Error::ColumnNotFound
|
||||||
/// [`ColumnIndexOutOfBounds`]: Error::ColumnIndexOutOfBounds
|
/// [`ColumnIndexOutOfBounds`]: Error::ColumnIndexOutOfBounds
|
||||||
///
|
///
|
||||||
fn try_get_raw<I>(
|
fn try_get_raw<I>(&self, index: I) -> Result<<Self::Database as Database>::ValueRef<'_>, Error>
|
||||||
&self,
|
|
||||||
index: I,
|
|
||||||
) -> Result<<Self::Database as HasValueRef<'_>>::ValueRef, Error>
|
|
||||||
where
|
where
|
||||||
I: ColumnIndex<Self>;
|
I: ColumnIndex<Self>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::arguments::IntoArguments;
|
use crate::arguments::IntoArguments;
|
||||||
use crate::column::ColumnIndex;
|
use crate::column::ColumnIndex;
|
||||||
use crate::database::{Database, HasArguments, HasStatement};
|
use crate::database::Database;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::from_row::FromRow;
|
use crate::from_row::FromRow;
|
||||||
use crate::query::Query;
|
use crate::query::Query;
|
||||||
|
@ -21,7 +21,7 @@ pub trait Statement<'q>: Send + Sync {
|
||||||
|
|
||||||
/// Creates an owned statement from this statement reference. This copies
|
/// Creates an owned statement from this statement reference. This copies
|
||||||
/// the original SQL text.
|
/// the original SQL text.
|
||||||
fn to_owned(&self) -> <Self::Database as HasStatement<'static>>::Statement;
|
fn to_owned(&self) -> <Self::Database as Database>::Statement<'static>;
|
||||||
|
|
||||||
/// Get the original SQL text used to create this statement.
|
/// Get the original SQL text used to create this statement.
|
||||||
fn sql(&self) -> &str;
|
fn sql(&self) -> &str;
|
||||||
|
@ -59,7 +59,7 @@ pub trait Statement<'q>: Send + Sync {
|
||||||
Ok(&self.columns()[index.index(self)?])
|
Ok(&self.columns()[index.index(self)?])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query(&self) -> Query<'_, Self::Database, <Self::Database as HasArguments<'_>>::Arguments>;
|
fn query(&self) -> Query<'_, Self::Database, <Self::Database as Database>::Arguments<'_>>;
|
||||||
|
|
||||||
fn query_with<'s, A>(&'s self, arguments: A) -> Query<'s, Self::Database, A>
|
fn query_with<'s, A>(&'s self, arguments: A) -> Query<'s, Self::Database, A>
|
||||||
where
|
where
|
||||||
|
@ -67,7 +67,7 @@ pub trait Statement<'q>: Send + Sync {
|
||||||
|
|
||||||
fn query_as<O>(
|
fn query_as<O>(
|
||||||
&self,
|
&self,
|
||||||
) -> QueryAs<'_, Self::Database, O, <Self::Database as HasArguments<'_>>::Arguments>
|
) -> QueryAs<'_, Self::Database, O, <Self::Database as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
O: for<'r> FromRow<'r, <Self::Database as Database>::Row>;
|
O: for<'r> FromRow<'r, <Self::Database as Database>::Row>;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ pub trait Statement<'q>: Send + Sync {
|
||||||
|
|
||||||
fn query_scalar<O>(
|
fn query_scalar<O>(
|
||||||
&self,
|
&self,
|
||||||
) -> QueryScalar<'_, Self::Database, O, <Self::Database as HasArguments<'_>>::Arguments>
|
) -> QueryScalar<'_, Self::Database, O, <Self::Database as Database>::Arguments<'_>>
|
||||||
where
|
where
|
||||||
(O,): for<'r> FromRow<'r, <Self::Database as Database>::Row>;
|
(O,): for<'r> FromRow<'r, <Self::Database as Database>::Row>;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ macro_rules! impl_statement_query {
|
||||||
'_,
|
'_,
|
||||||
Self::Database,
|
Self::Database,
|
||||||
O,
|
O,
|
||||||
<Self::Database as $crate::database::HasArguments<'_>>::Arguments,
|
<Self::Database as $crate::database::Database>::Arguments<'_>,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
O: for<'r> $crate::from_row::FromRow<
|
O: for<'r> $crate::from_row::FromRow<
|
||||||
|
@ -144,7 +144,7 @@ macro_rules! impl_statement_query {
|
||||||
'_,
|
'_,
|
||||||
Self::Database,
|
Self::Database,
|
||||||
O,
|
O,
|
||||||
<Self::Database as $crate::database::HasArguments<'_>>::Arguments,
|
<Self::Database as $crate::database::Database>::Arguments<'_>,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
(O,): for<'r> $crate::from_row::FromRow<
|
(O,): for<'r> $crate::from_row::FromRow<
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! TODO: automatic test fixture capture
|
//! TODO: automatic test fixture capture
|
||||||
|
|
||||||
use crate::database::{Database, HasArguments};
|
use crate::database::Database;
|
||||||
|
|
||||||
use crate::query_builder::QueryBuilder;
|
use crate::query_builder::QueryBuilder;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ impl<DB: Database> FixtureSnapshot<DB> {
|
||||||
/// which appends to an internal string.
|
/// which appends to an internal string.
|
||||||
impl<DB: Database> ToString for Fixture<DB>
|
impl<DB: Database> ToString for Fixture<DB>
|
||||||
where
|
where
|
||||||
for<'a> <DB as HasArguments<'a>>::Arguments: Default,
|
for<'a> <DB as Database>::Arguments<'a>: Default,
|
||||||
{
|
{
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut query = QueryBuilder::<DB>::new("");
|
let mut query = QueryBuilder::<DB>::new("");
|
||||||
|
|
|
@ -140,7 +140,7 @@ where
|
||||||
// ) -> futures_core::future::BoxFuture<
|
// ) -> futures_core::future::BoxFuture<
|
||||||
// 'e,
|
// 'e,
|
||||||
// Result<
|
// Result<
|
||||||
// <Self::Database as crate::database::HasStatement<'q>>::Statement,
|
// <Self::Database as crate::database::Database>::Statement<'q>,
|
||||||
// crate::error::Error,
|
// crate::error::Error,
|
||||||
// >,
|
// >,
|
||||||
// >
|
// >
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/// Conversions between `bstr` types and SQL types.
|
/// Conversions between `bstr` types and SQL types.
|
||||||
use crate::database::{Database, HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -27,7 +27,7 @@ where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
Vec<u8>: Decode<'r, DB>,
|
Vec<u8>: Decode<'r, DB>,
|
||||||
{
|
{
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
<Vec<u8> as Decode<DB>>::decode(value).map(BString::from)
|
<Vec<u8> as Decode<DB>>::decode(value).map(BString::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
&'q [u8]: Encode<'q, DB>,
|
&'q [u8]: Encode<'q, DB>,
|
||||||
{
|
{
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
<&[u8] as Encode<DB>>::encode(self.as_bytes(), buf)
|
<&[u8] as Encode<DB>>::encode(self.as_bytes(), buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
Vec<u8>: Encode<'q, DB>,
|
Vec<u8>: Encode<'q, DB>,
|
||||||
{
|
{
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
<Vec<u8> as Encode<DB>>::encode(self.as_bytes().to_vec(), buf)
|
<Vec<u8> as Encode<DB>>::encode(self.as_bytes().to_vec(), buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||||
pub use serde_json::value::RawValue as JsonRawValue;
|
pub use serde_json::value::RawValue as JsonRawValue;
|
||||||
pub use serde_json::Value as JsonValue;
|
pub use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
use crate::database::{Database, HasArguments, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::encode::{Encode, IsNull};
|
use crate::encode::{Encode, IsNull};
|
||||||
use crate::error::BoxDynError;
|
use crate::error::BoxDynError;
|
||||||
|
@ -141,7 +141,7 @@ where
|
||||||
for<'a> Json<&'a Self>: Encode<'q, DB>,
|
for<'a> Json<&'a Self>: Encode<'q, DB>,
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
<Json<&Self> as Encode<'q, DB>>::encode(Json(self), buf)
|
<Json<&Self> as Encode<'q, DB>>::encode(Json(self), buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ where
|
||||||
Json<Self>: Decode<'r, DB>,
|
Json<Self>: Decode<'r, DB>,
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
|
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ where
|
||||||
Json<Self>: Decode<'r, DB>,
|
Json<Self>: Decode<'r, DB>,
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
|
<Json<Self> as Decode<DB>>::decode(value).map(|item| item.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ where
|
||||||
String: Encode<'q, DB>,
|
String: Encode<'q, DB>,
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
fn encode_by_ref(&self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> IsNull {
|
||||||
self.0.to_string().encode(buf)
|
self.0.to_string().encode(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ where
|
||||||
&'r str: Decode<'r, DB>,
|
&'r str: Decode<'r, DB>,
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
|
||||||
Ok(Text(<&'r str as Decode<'r, DB>>::decode(value)?.parse()?))
|
Ok(Text(<&'r str as Decode<'r, DB>>::decode(value)?.parse()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{Database, HasValueRef};
|
use crate::database::Database;
|
||||||
use crate::decode::Decode;
|
use crate::decode::Decode;
|
||||||
use crate::error::{mismatched_types, Error};
|
use crate::error::{mismatched_types, Error};
|
||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
|
@ -10,7 +10,7 @@ pub trait Value {
|
||||||
type Database: Database;
|
type Database: Database;
|
||||||
|
|
||||||
/// Get this value as a reference.
|
/// Get this value as a reference.
|
||||||
fn as_ref(&self) -> <Self::Database as HasValueRef<'_>>::ValueRef;
|
fn as_ref(&self) -> <Self::Database as Database>::ValueRef<'_>;
|
||||||
|
|
||||||
/// Get the type information for this value.
|
/// Get the type information for this value.
|
||||||
fn type_info(&self) -> Cow<'_, <Self::Database as Database>::TypeInfo>;
|
fn type_info(&self) -> Cow<'_, <Self::Database as Database>::TypeInfo>;
|
||||||
|
|
|
@ -76,7 +76,7 @@ fn expand_derive_decode_transparent(
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics ::sqlx::decode::Decode<'r, DB> for #ident #ty_generics #where_clause {
|
impl #impl_generics ::sqlx::decode::Decode<'r, DB> for #ident #ty_generics #where_clause {
|
||||||
fn decode(
|
fn decode(
|
||||||
value: <DB as ::sqlx::database::HasValueRef<'r>>::ValueRef,
|
value: <DB as ::sqlx::database::Database>::ValueRef<'r>,
|
||||||
) -> ::std::result::Result<
|
) -> ::std::result::Result<
|
||||||
Self,
|
Self,
|
||||||
::std::boxed::Box<
|
::std::boxed::Box<
|
||||||
|
@ -118,7 +118,7 @@ fn expand_derive_decode_weak_enum(
|
||||||
#repr: ::sqlx::decode::Decode<'r, DB>,
|
#repr: ::sqlx::decode::Decode<'r, DB>,
|
||||||
{
|
{
|
||||||
fn decode(
|
fn decode(
|
||||||
value: <DB as ::sqlx::database::HasValueRef<'r>>::ValueRef,
|
value: <DB as ::sqlx::database::Database>::ValueRef<'r>,
|
||||||
) -> ::std::result::Result<
|
) -> ::std::result::Result<
|
||||||
Self,
|
Self,
|
||||||
::std::boxed::Box<
|
::std::boxed::Box<
|
||||||
|
|
|
@ -84,7 +84,7 @@ fn expand_derive_encode_transparent(
|
||||||
{
|
{
|
||||||
fn encode_by_ref(
|
fn encode_by_ref(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut <DB as ::sqlx::database::HasArguments<#lifetime>>::ArgumentBuffer,
|
buf: &mut <DB as ::sqlx::database::Database>::ArgumentBuffer<#lifetime>,
|
||||||
) -> ::sqlx::encode::IsNull {
|
) -> ::sqlx::encode::IsNull {
|
||||||
<#ty as ::sqlx::encode::Encode<#lifetime, DB>>::encode_by_ref(&self.0, buf)
|
<#ty as ::sqlx::encode::Encode<#lifetime, DB>>::encode_by_ref(&self.0, buf)
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ fn expand_derive_encode_weak_enum(
|
||||||
{
|
{
|
||||||
fn encode_by_ref(
|
fn encode_by_ref(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut <DB as ::sqlx::database::HasArguments<'q>>::ArgumentBuffer,
|
buf: &mut <DB as ::sqlx::database::Database>::ArgumentBuffer<'q>,
|
||||||
) -> ::sqlx::encode::IsNull {
|
) -> ::sqlx::encode::IsNull {
|
||||||
let value = match self {
|
let value = match self {
|
||||||
#(#values)*
|
#(#values)*
|
||||||
|
@ -173,7 +173,7 @@ fn expand_derive_encode_strong_enum(
|
||||||
{
|
{
|
||||||
fn encode_by_ref(
|
fn encode_by_ref(
|
||||||
&self,
|
&self,
|
||||||
buf: &mut <DB as ::sqlx::database::HasArguments<'q>>::ArgumentBuffer,
|
buf: &mut <DB as ::sqlx::database::Database>::ArgumentBuffer<'q>,
|
||||||
) -> ::sqlx::encode::IsNull {
|
) -> ::sqlx::encode::IsNull {
|
||||||
let val = match self {
|
let val = match self {
|
||||||
#(#value_arms)*
|
#(#value_arms)*
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn quote_args<DB: DatabaseExt>(
|
||||||
|
|
||||||
if input.arg_exprs.is_empty() {
|
if input.arg_exprs.is_empty() {
|
||||||
return Ok(quote! {
|
return Ok(quote! {
|
||||||
let query_args = <#db_path as ::sqlx::database::HasArguments>::Arguments::default();
|
let query_args = <#db_path as ::sqlx::database::Database>::Arguments::<'_>::default();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ pub fn quote_args<DB: DatabaseExt>(
|
||||||
|
|
||||||
#args_check
|
#args_check
|
||||||
|
|
||||||
let mut query_args = <#db_path as ::sqlx::database::HasArguments>::Arguments::default();
|
let mut query_args = <#db_path as ::sqlx::database::Database>::Arguments::<'_>::default();
|
||||||
query_args.reserve(
|
query_args.reserve(
|
||||||
#args_count,
|
#args_count,
|
||||||
0 #(+ ::sqlx::encode::Encode::<#db_path>::size_hint(#arg_name))*
|
0 #(+ ::sqlx::encode::Encode::<#db_path>::size_hint(#arg_name))*
|
||||||
|
|
|
@ -3,9 +3,7 @@ use crate::{
|
||||||
MySqlArguments, MySqlColumn, MySqlConnection, MySqlQueryResult, MySqlRow, MySqlStatement,
|
MySqlArguments, MySqlColumn, MySqlConnection, MySqlQueryResult, MySqlRow, MySqlStatement,
|
||||||
MySqlTransactionManager, MySqlTypeInfo,
|
MySqlTransactionManager, MySqlTypeInfo,
|
||||||
};
|
};
|
||||||
pub(crate) use sqlx_core::database::{
|
pub(crate) use sqlx_core::database::{Database, HasStatementCache};
|
||||||
Database, HasArguments, HasStatement, HasStatementCache, HasValueRef,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// MySQL database driver.
|
/// MySQL database driver.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -25,30 +23,16 @@ impl Database for MySql {
|
||||||
type TypeInfo = MySqlTypeInfo;
|
type TypeInfo = MySqlTypeInfo;
|
||||||
|
|
||||||
type Value = MySqlValue;
|
type Value = MySqlValue;
|
||||||
|
type ValueRef<'r> = MySqlValueRef<'r>;
|
||||||
|
|
||||||
|
type Arguments<'q> = MySqlArguments;
|
||||||
|
type ArgumentBuffer<'q> = Vec<u8>;
|
||||||
|
|
||||||
|
type Statement<'q> = MySqlStatement<'q>;
|
||||||
|
|
||||||
const NAME: &'static str = "MySQL";
|
const NAME: &'static str = "MySQL";
|
||||||
|
|
||||||
const URL_SCHEMES: &'static [&'static str] = &["mysql", "mariadb"];
|
const URL_SCHEMES: &'static [&'static str] = &["mysql", "mariadb"];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> HasValueRef<'r> for MySql {
|
|
||||||
type Database = MySql;
|
|
||||||
|
|
||||||
type ValueRef = MySqlValueRef<'r>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasArguments<'_> for MySql {
|
|
||||||
type Database = MySql;
|
|
||||||
|
|
||||||
type Arguments = MySqlArguments;
|
|
||||||
|
|
||||||
type ArgumentBuffer = Vec<u8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasStatement<'q> for MySql {
|
|
||||||
type Database = MySql;
|
|
||||||
|
|
||||||
type Statement = MySqlStatement<'q>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasStatementCache for MySql {}
|
impl HasStatementCache for MySql {}
|
||||||
|
|
|
@ -5,9 +5,7 @@ use crate::{
|
||||||
PgTypeInfo,
|
PgTypeInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use sqlx_core::database::{
|
pub(crate) use sqlx_core::database::{Database, HasStatementCache};
|
||||||
Database, HasArguments, HasStatement, HasStatementCache, HasValueRef,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// PostgreSQL database driver.
|
/// PostgreSQL database driver.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -27,30 +25,16 @@ impl Database for Postgres {
|
||||||
type TypeInfo = PgTypeInfo;
|
type TypeInfo = PgTypeInfo;
|
||||||
|
|
||||||
type Value = PgValue;
|
type Value = PgValue;
|
||||||
|
type ValueRef<'r> = PgValueRef<'r>;
|
||||||
|
|
||||||
|
type Arguments<'q> = PgArguments;
|
||||||
|
type ArgumentBuffer<'q> = PgArgumentBuffer;
|
||||||
|
|
||||||
|
type Statement<'q> = PgStatement<'q>;
|
||||||
|
|
||||||
const NAME: &'static str = "PostgreSQL";
|
const NAME: &'static str = "PostgreSQL";
|
||||||
|
|
||||||
const URL_SCHEMES: &'static [&'static str] = &["postgres", "postgresql"];
|
const URL_SCHEMES: &'static [&'static str] = &["postgres", "postgresql"];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> HasValueRef<'r> for Postgres {
|
|
||||||
type Database = Postgres;
|
|
||||||
|
|
||||||
type ValueRef = PgValueRef<'r>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasArguments<'_> for Postgres {
|
|
||||||
type Database = Postgres;
|
|
||||||
|
|
||||||
type Arguments = PgArguments;
|
|
||||||
|
|
||||||
type ArgumentBuffer = PgArgumentBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasStatement<'q> for Postgres {
|
|
||||||
type Database = Postgres;
|
|
||||||
|
|
||||||
type Statement = PgStatement<'q>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasStatementCache for Postgres {}
|
impl HasStatementCache for Postgres {}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
pub(crate) use sqlx_core::database::{
|
pub(crate) use sqlx_core::database::{Database, HasStatementCache};
|
||||||
Database, HasArguments, HasStatement, HasStatementCache, HasValueRef,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
SqliteArgumentValue, SqliteArguments, SqliteColumn, SqliteConnection, SqliteQueryResult,
|
SqliteArgumentValue, SqliteArguments, SqliteColumn, SqliteConnection, SqliteQueryResult,
|
||||||
|
@ -26,30 +24,16 @@ impl Database for Sqlite {
|
||||||
type TypeInfo = SqliteTypeInfo;
|
type TypeInfo = SqliteTypeInfo;
|
||||||
|
|
||||||
type Value = SqliteValue;
|
type Value = SqliteValue;
|
||||||
|
type ValueRef<'r> = SqliteValueRef<'r>;
|
||||||
|
|
||||||
|
type Arguments<'q> = SqliteArguments<'q>;
|
||||||
|
type ArgumentBuffer<'q> = Vec<SqliteArgumentValue<'q>>;
|
||||||
|
|
||||||
|
type Statement<'q> = SqliteStatement<'q>;
|
||||||
|
|
||||||
const NAME: &'static str = "SQLite";
|
const NAME: &'static str = "SQLite";
|
||||||
|
|
||||||
const URL_SCHEMES: &'static [&'static str] = &["sqlite"];
|
const URL_SCHEMES: &'static [&'static str] = &["sqlite"];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> HasValueRef<'r> for Sqlite {
|
|
||||||
type Database = Sqlite;
|
|
||||||
|
|
||||||
type ValueRef = SqliteValueRef<'r>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasArguments<'q> for Sqlite {
|
|
||||||
type Database = Sqlite;
|
|
||||||
|
|
||||||
type Arguments = SqliteArguments<'q>;
|
|
||||||
|
|
||||||
type ArgumentBuffer = Vec<SqliteArgumentValue<'q>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'q> HasStatement<'q> for Sqlite {
|
|
||||||
type Database = Sqlite;
|
|
||||||
|
|
||||||
type Statement = SqliteStatement<'q>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasStatementCache for Sqlite {}
|
impl HasStatementCache for Sqlite {}
|
||||||
|
|
Loading…
Reference in a new issue