mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
refactor(sqlite): do not borrow bound values, delete lifetime on SqliteArguments (#3957)
* bug(sqlite): query macro argument lifetime use inconsistent with other db platforms Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> * refactor(sqlite): Improve support for references as query macro bind arguments by removing lifetime parameter from SqliteArguments Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> * refactor(sqlite): Introduce SqliteArgumentsBuffer type Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> * refactor(sqlite): Improve cloning of SqliteArgumentValue, SqliteArguments, and SqliteArgumentsBuffer Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> * refactor(any): Simplify AnyArguments::convert_to to convert_into Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com> --------- Signed-off-by: Joshua Potts <8704475+iamjpotts@users.noreply.github.com>
This commit is contained in:
parent
e77f32ea5e
commit
ff93aa017a
@ -42,7 +42,7 @@ impl Default for AnyArguments<'_> {
|
||||
|
||||
impl<'q> AnyArguments<'q> {
|
||||
#[doc(hidden)]
|
||||
pub fn convert_to<'a, A: Arguments<'a>>(&'a self) -> Result<A, BoxDynError>
|
||||
pub fn convert_into<'a, A: Arguments<'a>>(self) -> Result<A, BoxDynError>
|
||||
where
|
||||
'q: 'a,
|
||||
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
@ -60,12 +60,12 @@ impl<'q> AnyArguments<'q> {
|
||||
i64: Type<A::Database> + Encode<'a, A::Database>,
|
||||
f32: Type<A::Database> + Encode<'a, A::Database>,
|
||||
f64: Type<A::Database> + Encode<'a, A::Database>,
|
||||
&'a str: Type<A::Database> + Encode<'a, A::Database>,
|
||||
&'a [u8]: Type<A::Database> + Encode<'a, A::Database>,
|
||||
String: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Vec<u8>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
{
|
||||
let mut out = A::default();
|
||||
|
||||
for arg in &self.values.0 {
|
||||
for arg in self.values.0 {
|
||||
match arg {
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Null) => out.add(Option::<i32>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Bool) => out.add(Option::<bool>::None),
|
||||
@ -82,8 +82,8 @@ impl<'q> AnyArguments<'q> {
|
||||
AnyValueKind::BigInt(i) => out.add(i),
|
||||
AnyValueKind::Real(r) => out.add(r),
|
||||
AnyValueKind::Double(d) => out.add(d),
|
||||
AnyValueKind::Text(t) => out.add(&**t),
|
||||
AnyValueKind::Blob(b) => out.add(&**b),
|
||||
AnyValueKind::Text(t) => out.add(String::from(t)),
|
||||
AnyValueKind::Blob(b) => out.add(Vec::from(b)),
|
||||
}?
|
||||
}
|
||||
Ok(out)
|
||||
|
||||
@ -84,7 +84,7 @@ impl AnyConnectionBackend for MySqlConnection {
|
||||
arguments: Option<AnyArguments<'q>>,
|
||||
) -> BoxStream<'q, sqlx_core::Result<Either<AnyQueryResult, AnyRow>>> {
|
||||
let persistent = persistent && arguments.is_some();
|
||||
let arguments = match arguments.as_ref().map(AnyArguments::convert_to).transpose() {
|
||||
let arguments = match arguments.map(AnyArguments::convert_into).transpose() {
|
||||
Ok(arguments) => arguments,
|
||||
Err(error) => {
|
||||
return stream::once(future::ready(Err(sqlx_core::Error::Encode(error)))).boxed()
|
||||
@ -111,8 +111,7 @@ impl AnyConnectionBackend for MySqlConnection {
|
||||
) -> BoxFuture<'q, sqlx_core::Result<Option<AnyRow>>> {
|
||||
let persistent = persistent && arguments.is_some();
|
||||
let arguments = arguments
|
||||
.as_ref()
|
||||
.map(AnyArguments::convert_to)
|
||||
.map(AnyArguments::convert_into)
|
||||
.transpose()
|
||||
.map_err(sqlx_core::Error::Encode);
|
||||
|
||||
|
||||
@ -86,7 +86,7 @@ impl AnyConnectionBackend for PgConnection {
|
||||
arguments: Option<AnyArguments<'q>>,
|
||||
) -> BoxStream<'q, sqlx_core::Result<Either<AnyQueryResult, AnyRow>>> {
|
||||
let persistent = persistent && arguments.is_some();
|
||||
let arguments = match arguments.as_ref().map(AnyArguments::convert_to).transpose() {
|
||||
let arguments = match arguments.map(AnyArguments::convert_into).transpose() {
|
||||
Ok(arguments) => arguments,
|
||||
Err(error) => {
|
||||
return stream::once(future::ready(Err(sqlx_core::Error::Encode(error)))).boxed()
|
||||
@ -113,8 +113,7 @@ impl AnyConnectionBackend for PgConnection {
|
||||
) -> BoxFuture<'q, sqlx_core::Result<Option<AnyRow>>> {
|
||||
let persistent = persistent && arguments.is_some();
|
||||
let arguments = arguments
|
||||
.as_ref()
|
||||
.map(AnyArguments::convert_to)
|
||||
.map(AnyArguments::convert_into)
|
||||
.transpose()
|
||||
.map_err(sqlx_core::Error::Encode);
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ use sqlx_core::any::{
|
||||
};
|
||||
use sqlx_core::sql_str::SqlStr;
|
||||
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::type_info::DataType;
|
||||
use sqlx_core::connection::{ConnectOptions, Connection};
|
||||
use sqlx_core::database::Database;
|
||||
@ -19,6 +20,7 @@ use sqlx_core::describe::Describe;
|
||||
use sqlx_core::executor::Executor;
|
||||
use sqlx_core::transaction::TransactionManager;
|
||||
use std::pin::pin;
|
||||
use std::sync::Arc;
|
||||
|
||||
sqlx_core::declare_driver_with_optional_migrate!(DRIVER = Sqlite);
|
||||
|
||||
@ -203,27 +205,29 @@ impl<'a> TryFrom<&'a AnyConnectOptions> for SqliteConnectOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/// Instead of `AnyArguments::convert_into()`, we can do a direct mapping and preserve the lifetime.
|
||||
fn map_arguments(args: AnyArguments<'_>) -> SqliteArguments<'_> {
|
||||
// Infallible alternative to AnyArguments::convert_into()
|
||||
fn map_arguments(args: AnyArguments<'_>) -> SqliteArguments {
|
||||
let values = args
|
||||
.values
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|val| match val {
|
||||
AnyValueKind::Null(_) => SqliteArgumentValue::Null,
|
||||
AnyValueKind::Bool(b) => SqliteArgumentValue::Int(b as i32),
|
||||
AnyValueKind::SmallInt(i) => SqliteArgumentValue::Int(i as i32),
|
||||
AnyValueKind::Integer(i) => SqliteArgumentValue::Int(i),
|
||||
AnyValueKind::BigInt(i) => SqliteArgumentValue::Int64(i),
|
||||
AnyValueKind::Real(r) => SqliteArgumentValue::Double(r as f64),
|
||||
AnyValueKind::Double(d) => SqliteArgumentValue::Double(d),
|
||||
AnyValueKind::Text(t) => SqliteArgumentValue::Text(Arc::new(t.to_string())),
|
||||
AnyValueKind::Blob(b) => SqliteArgumentValue::Blob(Arc::new(b.to_vec())),
|
||||
// AnyValueKind is `#[non_exhaustive]` but we should have covered everything
|
||||
_ => unreachable!("BUG: missing mapping for {val:?}"),
|
||||
})
|
||||
.collect();
|
||||
|
||||
SqliteArguments {
|
||||
values: args
|
||||
.values
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|val| match val {
|
||||
AnyValueKind::Null(_) => SqliteArgumentValue::Null,
|
||||
AnyValueKind::Bool(b) => SqliteArgumentValue::Int(b as i32),
|
||||
AnyValueKind::SmallInt(i) => SqliteArgumentValue::Int(i as i32),
|
||||
AnyValueKind::Integer(i) => SqliteArgumentValue::Int(i),
|
||||
AnyValueKind::BigInt(i) => SqliteArgumentValue::Int64(i),
|
||||
AnyValueKind::Real(r) => SqliteArgumentValue::Double(r as f64),
|
||||
AnyValueKind::Double(d) => SqliteArgumentValue::Double(d),
|
||||
AnyValueKind::Text(t) => SqliteArgumentValue::Text(t),
|
||||
AnyValueKind::Blob(b) => SqliteArgumentValue::Blob(b),
|
||||
// AnyValueKind is `#[non_exhaustive]` but we should have covered everything
|
||||
_ => unreachable!("BUG: missing mapping for {val:?}"),
|
||||
})
|
||||
.collect(),
|
||||
values: SqliteArgumentsBuffer::new(values),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,62 +4,56 @@ use crate::statement::StatementHandle;
|
||||
use crate::Sqlite;
|
||||
use atoi::atoi;
|
||||
use libsqlite3_sys::SQLITE_OK;
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) use sqlx_core::arguments::*;
|
||||
use sqlx_core::error::BoxDynError;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SqliteArgumentValue<'q> {
|
||||
pub enum SqliteArgumentValue {
|
||||
Null,
|
||||
Text(Cow<'q, str>),
|
||||
Blob(Cow<'q, [u8]>),
|
||||
Text(Arc<String>),
|
||||
TextSlice(Arc<str>),
|
||||
Blob(Arc<Vec<u8>>),
|
||||
Double(f64),
|
||||
Int(i32),
|
||||
Int64(i64),
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SqliteArguments<'q> {
|
||||
pub(crate) values: Vec<SqliteArgumentValue<'q>>,
|
||||
pub struct SqliteArguments {
|
||||
pub(crate) values: SqliteArgumentsBuffer,
|
||||
}
|
||||
|
||||
impl<'q> SqliteArguments<'q> {
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SqliteArgumentsBuffer(Vec<SqliteArgumentValue>);
|
||||
|
||||
impl<'q> SqliteArguments {
|
||||
pub(crate) fn add<T>(&mut self, value: T) -> Result<(), BoxDynError>
|
||||
where
|
||||
T: Encode<'q, Sqlite>,
|
||||
{
|
||||
let value_length_before_encoding = self.values.len();
|
||||
let value_length_before_encoding = self.values.0.len();
|
||||
|
||||
match value.encode(&mut self.values) {
|
||||
Ok(IsNull::Yes) => self.values.push(SqliteArgumentValue::Null),
|
||||
Ok(IsNull::Yes) => self.values.0.push(SqliteArgumentValue::Null),
|
||||
Ok(IsNull::No) => {}
|
||||
Err(error) => {
|
||||
// reset the value buffer to its previous value if encoding failed so we don't leave a half-encoded value behind
|
||||
self.values.truncate(value_length_before_encoding);
|
||||
self.values.0.truncate(value_length_before_encoding);
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn into_static(self) -> SqliteArguments<'static> {
|
||||
SqliteArguments {
|
||||
values: self
|
||||
.values
|
||||
.into_iter()
|
||||
.map(SqliteArgumentValue::into_static)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Arguments<'q> for SqliteArguments<'q> {
|
||||
impl<'q> Arguments<'q> for SqliteArguments {
|
||||
type Database = Sqlite;
|
||||
|
||||
fn reserve(&mut self, len: usize, _size_hint: usize) {
|
||||
self.values.reserve(len);
|
||||
self.values.0.reserve(len);
|
||||
}
|
||||
|
||||
fn add<T>(&mut self, value: T) -> Result<(), BoxDynError>
|
||||
@ -70,11 +64,11 @@ impl<'q> Arguments<'q> for SqliteArguments<'q> {
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.values.len()
|
||||
self.values.0.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl SqliteArguments<'_> {
|
||||
impl SqliteArguments {
|
||||
pub(super) fn bind(&self, handle: &mut StatementHandle, offset: usize) -> Result<usize, Error> {
|
||||
let mut arg_i = offset;
|
||||
// for handle in &statement.handles {
|
||||
@ -103,7 +97,7 @@ impl SqliteArguments<'_> {
|
||||
arg_i
|
||||
};
|
||||
|
||||
if n > self.values.len() {
|
||||
if n > self.values.0.len() {
|
||||
// SQLite treats unbound variables as NULL
|
||||
// we reproduce this here
|
||||
// If you are reading this and think this should be an error, open an issue and we can
|
||||
@ -113,32 +107,31 @@ impl SqliteArguments<'_> {
|
||||
break;
|
||||
}
|
||||
|
||||
self.values[n - 1].bind(handle, param_i)?;
|
||||
self.values.0[n - 1].bind(handle, param_i)?;
|
||||
}
|
||||
|
||||
Ok(arg_i - offset)
|
||||
}
|
||||
}
|
||||
|
||||
impl SqliteArgumentValue<'_> {
|
||||
fn into_static(self) -> SqliteArgumentValue<'static> {
|
||||
use SqliteArgumentValue::*;
|
||||
|
||||
match self {
|
||||
Null => Null,
|
||||
Text(text) => Text(text.into_owned().into()),
|
||||
Blob(blob) => Blob(blob.into_owned().into()),
|
||||
Int(v) => Int(v),
|
||||
Int64(v) => Int64(v),
|
||||
Double(v) => Double(v),
|
||||
}
|
||||
impl SqliteArgumentsBuffer {
|
||||
#[allow(dead_code)] // clippy incorrectly reports this as unused
|
||||
pub(crate) fn new(values: Vec<SqliteArgumentValue>) -> SqliteArgumentsBuffer {
|
||||
Self(values)
|
||||
}
|
||||
|
||||
pub(crate) fn push(&mut self, value: SqliteArgumentValue) {
|
||||
self.0.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
impl SqliteArgumentValue {
|
||||
fn bind(&self, handle: &mut StatementHandle, i: usize) -> Result<(), Error> {
|
||||
use SqliteArgumentValue::*;
|
||||
|
||||
let status = match self {
|
||||
Text(v) => handle.bind_text(i, v),
|
||||
TextSlice(v) => handle.bind_text(i, v),
|
||||
Blob(v) => handle.bind_blob(i, v),
|
||||
Int(v) => handle.bind_int(i, *v),
|
||||
Int64(v) => handle.bind_int64(i, *v),
|
||||
|
||||
@ -10,7 +10,7 @@ pub struct ExecuteIter<'a> {
|
||||
handle: &'a mut ConnectionHandle,
|
||||
statement: &'a mut VirtualStatement,
|
||||
logger: QueryLogger,
|
||||
args: Option<SqliteArguments<'a>>,
|
||||
args: Option<SqliteArguments>,
|
||||
|
||||
/// since a `VirtualStatement` can encompass multiple actual statements,
|
||||
/// this keeps track of the number of arguments so far
|
||||
@ -19,12 +19,12 @@ pub struct ExecuteIter<'a> {
|
||||
goto_next: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn iter<'a>(
|
||||
conn: &'a mut ConnectionState,
|
||||
pub(crate) fn iter(
|
||||
conn: &mut ConnectionState,
|
||||
query: impl SqlSafeStr,
|
||||
args: Option<SqliteArguments<'a>>,
|
||||
args: Option<SqliteArguments>,
|
||||
persistent: bool,
|
||||
) -> Result<ExecuteIter<'a>, Error> {
|
||||
) -> Result<ExecuteIter<'_>, Error> {
|
||||
let query = query.into_sql_str();
|
||||
// fetch the cached statement or allocate a new one
|
||||
let statement = conn.statements.get(query.as_str(), persistent)?;
|
||||
@ -43,7 +43,7 @@ pub(crate) fn iter<'a>(
|
||||
|
||||
fn bind(
|
||||
statement: &mut StatementHandle,
|
||||
arguments: &Option<SqliteArguments<'_>>,
|
||||
arguments: &Option<SqliteArguments>,
|
||||
offset: usize,
|
||||
) -> Result<usize, Error> {
|
||||
let mut n = 0;
|
||||
@ -56,7 +56,7 @@ fn bind(
|
||||
}
|
||||
|
||||
impl ExecuteIter<'_> {
|
||||
pub fn finish(&mut self) -> Result<(), Error> {
|
||||
pub fn finish(self) -> Result<(), Error> {
|
||||
for res in self {
|
||||
let _ = res?;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ enum Command {
|
||||
},
|
||||
Execute {
|
||||
query: SqlStr,
|
||||
arguments: Option<SqliteArguments<'static>>,
|
||||
arguments: Option<SqliteArguments>,
|
||||
persistent: bool,
|
||||
tx: flume::Sender<Result<Either<SqliteQueryResult, SqliteRow>, Error>>,
|
||||
limit: Option<usize>,
|
||||
@ -360,7 +360,7 @@ impl ConnectionWorker {
|
||||
pub(crate) async fn execute(
|
||||
&mut self,
|
||||
query: SqlStr,
|
||||
args: Option<SqliteArguments<'_>>,
|
||||
args: Option<SqliteArguments>,
|
||||
chan_size: usize,
|
||||
persistent: bool,
|
||||
limit: Option<usize>,
|
||||
@ -371,7 +371,7 @@ impl ConnectionWorker {
|
||||
.send_async((
|
||||
Command::Execute {
|
||||
query,
|
||||
arguments: args.map(SqliteArguments::into_static),
|
||||
arguments: args,
|
||||
persistent,
|
||||
tx,
|
||||
limit,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
pub(crate) use sqlx_core::database::{Database, HasStatementCache};
|
||||
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::{
|
||||
SqliteArgumentValue, SqliteArguments, SqliteColumn, SqliteConnection, SqliteQueryResult,
|
||||
SqliteRow, SqliteStatement, SqliteTransactionManager, SqliteTypeInfo, SqliteValue,
|
||||
SqliteValueRef,
|
||||
SqliteArguments, SqliteColumn, SqliteConnection, SqliteQueryResult, SqliteRow, SqliteStatement,
|
||||
SqliteTransactionManager, SqliteTypeInfo, SqliteValue, SqliteValueRef,
|
||||
};
|
||||
|
||||
/// Sqlite database driver.
|
||||
@ -26,8 +26,8 @@ impl Database for Sqlite {
|
||||
type Value = SqliteValue;
|
||||
type ValueRef<'r> = SqliteValueRef<'r>;
|
||||
|
||||
type Arguments<'q> = SqliteArguments<'q>;
|
||||
type ArgumentBuffer<'q> = Vec<SqliteArgumentValue<'q>>;
|
||||
type Arguments<'q> = SqliteArguments;
|
||||
type ArgumentBuffer<'q> = SqliteArgumentsBuffer;
|
||||
|
||||
type Statement = SqliteStatement;
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@ extern crate sqlx_core;
|
||||
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
pub use arguments::{SqliteArgumentValue, SqliteArguments};
|
||||
pub use arguments::{SqliteArgumentValue, SqliteArguments, SqliteArgumentsBuffer};
|
||||
pub use column::SqliteColumn;
|
||||
#[cfg(feature = "deserialize")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "deserialize")))]
|
||||
@ -147,7 +147,7 @@ impl<'c, T: Executor<'c, Database = Sqlite>> SqliteExecutor<'c> for T {}
|
||||
pub type SqliteTransaction<'c> = sqlx_core::transaction::Transaction<'c, Sqlite>;
|
||||
|
||||
// NOTE: required due to the lack of lazy normalization
|
||||
impl_into_arguments_for_arguments!(SqliteArguments<'q>);
|
||||
impl_into_arguments_for_arguments!(SqliteArguments);
|
||||
impl_column_index_for_row!(SqliteRow);
|
||||
impl_column_index_for_statement!(SqliteStatement);
|
||||
impl_acquire!(Sqlite, SqliteConnection);
|
||||
|
||||
@ -45,7 +45,7 @@ impl Statement for SqliteStatement {
|
||||
&self.columns
|
||||
}
|
||||
|
||||
impl_statement_query!(SqliteArguments<'_>);
|
||||
impl_statement_query!(SqliteArguments);
|
||||
}
|
||||
|
||||
impl ColumnIndex<SqliteStatement> for &'_ str {
|
||||
@ -57,20 +57,3 @@ impl ColumnIndex<SqliteStatement> for &'_ str {
|
||||
.copied()
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(feature = "any")]
|
||||
// impl<'q> From<SqliteStatement<'q>> for crate::any::AnyStatement<'q> {
|
||||
// #[inline]
|
||||
// fn from(statement: SqliteStatement<'q>) -> Self {
|
||||
// crate::any::AnyStatement::<'q> {
|
||||
// columns: statement
|
||||
// .columns
|
||||
// .iter()
|
||||
// .map(|col| col.clone().into())
|
||||
// .collect(),
|
||||
// column_names: statement.column_names,
|
||||
// parameters: Some(Either::Right(statement.parameters)),
|
||||
// sql: statement.sql,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -15,11 +16,8 @@ impl Type<Sqlite> for bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for bool {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for bool {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int((*self).into()));
|
||||
|
||||
Ok(IsNull::No)
|
||||
|
||||
@ -2,6 +2,7 @@ use std::borrow::Cow;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -19,12 +20,9 @@ impl Type<Sqlite> for [u8] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for &'q [u8] {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Borrowed(self)));
|
||||
impl Encode<'_, Sqlite> for &'_ [u8] {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.to_vec())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -37,19 +35,14 @@ impl<'r> Decode<'r, Sqlite> for &'r [u8] {
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for Box<[u8]> {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(self.into_vec())));
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.into_vec())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'_>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(
|
||||
self.clone().into_vec(),
|
||||
)));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.clone().into_vec())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -65,18 +58,15 @@ impl Type<Sqlite> for Vec<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Vec<u8> {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(self)));
|
||||
impl Encode<'_, Sqlite> for Vec<u8> {
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self)));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(self.clone())));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.clone())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -88,37 +78,28 @@ impl<'r> Decode<'r, Sqlite> for Vec<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Cow<'q, [u8]> {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(self));
|
||||
impl Encode<'_, Sqlite> for Cow<'_, [u8]> {
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.into())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(self.clone()));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(self.to_vec())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Arc<[u8]> {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for Arc<[u8]> {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
<Vec<u8> as Encode<'_, Sqlite>>::encode(self.to_vec(), args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Rc<[u8]> {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for Rc<[u8]> {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
<Vec<u8> as Encode<'_, Sqlite>>::encode(self.to_vec(), args)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::{
|
||||
error::BoxDynError,
|
||||
type_info::DataType,
|
||||
types::Type,
|
||||
Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef,
|
||||
Sqlite, SqliteArgumentsBuffer, SqliteTypeInfo, SqliteValueRef,
|
||||
};
|
||||
use chrono::FixedOffset;
|
||||
use chrono::{
|
||||
@ -65,25 +65,25 @@ impl<Tz: TimeZone> Encode<'_, Sqlite> for DateTime<Tz>
|
||||
where
|
||||
Tz::Offset: Display,
|
||||
{
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.to_rfc3339_opts(SecondsFormat::AutoSi, false), buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for NaiveDateTime {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.format("%F %T%.f").to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for NaiveDate {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.format("%F").to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for NaiveTime {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.format("%T%.f").to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -11,11 +12,8 @@ impl Type<Sqlite> for f32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for f32 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for f32 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Double((*self).into()));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -36,11 +34,8 @@ impl Type<Sqlite> for f64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for f64 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for f64 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Double(*self));
|
||||
|
||||
Ok(IsNull::No)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -15,11 +16,8 @@ impl Type<Sqlite> for i8 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for i8 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for i8 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int(*self as i32));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -46,11 +44,8 @@ impl Type<Sqlite> for i16 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for i16 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for i16 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int(*self as i32));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -73,11 +68,8 @@ impl Type<Sqlite> for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for i32 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for i32 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int(*self));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -100,11 +92,8 @@ impl Type<Sqlite> for i64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for i64 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for i64 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int64(*self));
|
||||
|
||||
Ok(IsNull::No)
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
use crate::types::{Json, Type};
|
||||
use crate::{type_info::DataType, Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef};
|
||||
use crate::{type_info::DataType, Sqlite, SqliteTypeInfo, SqliteValueRef};
|
||||
|
||||
impl<T> Type<Sqlite> for Json<T> {
|
||||
fn type_info() -> SqliteTypeInfo {
|
||||
@ -20,7 +21,7 @@ impl<T> Encode<'_, Sqlite> for Json<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.encode_to_string()?, buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
use std::borrow::Cow;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
use crate::type_info::DataType;
|
||||
use crate::types::Type;
|
||||
use crate::{Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef};
|
||||
use sqlx_core::database::Database;
|
||||
use std::borrow::Cow;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl Type<Sqlite> for str {
|
||||
fn type_info() -> SqliteTypeInfo {
|
||||
@ -15,12 +16,9 @@ impl Type<Sqlite> for str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for &'q str {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Borrowed(*self)));
|
||||
impl Encode<'_, Sqlite> for &'_ str {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.to_string())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -33,19 +31,14 @@ impl<'r> Decode<'r, Sqlite> for &'r str {
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for Box<str> {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(self.into_string())));
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::TextSlice(Arc::from(self)));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'_>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(
|
||||
self.clone().into_string(),
|
||||
)));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.to_string())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -57,18 +50,15 @@ impl Type<Sqlite> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for String {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(self)));
|
||||
impl Encode<'_, Sqlite> for String {
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self)));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(self.clone())));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.clone())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -80,37 +70,40 @@ impl<'r> Decode<'r, Sqlite> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Cow<'q, str> {
|
||||
fn encode(self, args: &mut Vec<SqliteArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(self));
|
||||
impl Encode<'_, Sqlite> for Cow<'_, str> {
|
||||
fn encode(self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.into())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(self.clone()));
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.to_string())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Arc<str> {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for Arc<str> {
|
||||
fn encode(
|
||||
self,
|
||||
args: &mut <Sqlite as Database>::ArgumentBuffer<'_>,
|
||||
) -> Result<IsNull, BoxDynError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
args.push(SqliteArgumentValue::TextSlice(self));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
<String as Encode<'_, Sqlite>>::encode(self.to_string(), args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Rc<str> {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for Rc<str> {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
<String as Encode<'_, Sqlite>>::encode(self.to_string(), args)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::{Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef};
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::{Sqlite, SqliteTypeInfo, SqliteValueRef};
|
||||
use sqlx_core::decode::Decode;
|
||||
use sqlx_core::encode::{Encode, IsNull};
|
||||
use sqlx_core::error::BoxDynError;
|
||||
@ -16,11 +17,11 @@ impl<T> Type<Sqlite> for Text<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q, T> Encode<'q, Sqlite> for Text<T>
|
||||
impl<T> Encode<'_, Sqlite> for Text<T>
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.0.to_string(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::value::ValueRef;
|
||||
use crate::{
|
||||
decode::Decode,
|
||||
@ -5,7 +6,7 @@ use crate::{
|
||||
error::BoxDynError,
|
||||
type_info::DataType,
|
||||
types::Type,
|
||||
Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef,
|
||||
Sqlite, SqliteTypeInfo, SqliteValueRef,
|
||||
};
|
||||
use time::format_description::{well_known::Rfc3339, BorrowedFormatItem};
|
||||
use time::macros::format_description as fd;
|
||||
@ -55,27 +56,27 @@ impl Type<Sqlite> for Time {
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for OffsetDateTime {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
Encode::<Sqlite>::encode(self.format(&Rfc3339)?, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for PrimitiveDateTime {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
let format = fd!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]");
|
||||
Encode::<Sqlite>::encode(self.format(&format)?, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for Date {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
let format = fd!("[year]-[month]-[day]");
|
||||
Encode::<Sqlite>::encode(self.format(&format)?, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Sqlite> for Time {
|
||||
fn encode_by_ref(&self, buf: &mut Vec<SqliteArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
|
||||
fn encode_by_ref(&self, buf: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
let format = fd!("[hour]:[minute]:[second].[subsecond]");
|
||||
Encode::<Sqlite>::encode(self.format(&format)?, buf)
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -15,11 +16,8 @@ impl Type<Sqlite> for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for u8 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for u8 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int(*self as i32));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -46,11 +44,8 @@ impl Type<Sqlite> for u16 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for u16 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for u16 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int(*self as i32));
|
||||
|
||||
Ok(IsNull::No)
|
||||
@ -73,11 +68,8 @@ impl Type<Sqlite> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for u32 {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
impl Encode<'_, Sqlite> for u32 {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Int64(*self as i64));
|
||||
|
||||
Ok(IsNull::No)
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use crate::arguments::SqliteArgumentsBuffer;
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
use crate::type_info::DataType;
|
||||
use crate::types::Type;
|
||||
use crate::{Sqlite, SqliteArgumentValue, SqliteTypeInfo, SqliteValueRef};
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
use uuid::{
|
||||
fmt::{Hyphenated, Simple},
|
||||
Uuid,
|
||||
@ -20,12 +21,9 @@ impl Type<Sqlite> for Uuid {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Uuid {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Cow::Owned(
|
||||
impl Encode<'_, Sqlite> for Uuid {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Blob(Arc::new(
|
||||
self.as_bytes().to_vec(),
|
||||
)));
|
||||
|
||||
@ -46,12 +44,9 @@ impl Type<Sqlite> for Hyphenated {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Hyphenated {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(self.to_string())));
|
||||
impl Encode<'_, Sqlite> for Hyphenated {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.to_string())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
@ -72,12 +67,9 @@ impl Type<Sqlite> for Simple {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, Sqlite> for Simple {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
args: &mut Vec<SqliteArgumentValue<'q>>,
|
||||
) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Cow::Owned(self.to_string())));
|
||||
impl Encode<'_, Sqlite> for Simple {
|
||||
fn encode_by_ref(&self, args: &mut SqliteArgumentsBuffer) -> Result<IsNull, BoxDynError> {
|
||||
args.push(SqliteArgumentValue::Text(Arc::new(self.to_string())));
|
||||
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
|
||||
@ -175,6 +175,31 @@ async fn test_query_scalar() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx_macros::test]
|
||||
async fn query_by_string() -> anyhow::Result<()> {
|
||||
let mut conn = new::<Sqlite>().await?;
|
||||
|
||||
let string = "Hello, world!".to_string();
|
||||
let ref tuple = ("Hello, world!".to_string(),);
|
||||
|
||||
let result = sqlx::query!(
|
||||
"SELECT 'Hello, world!' as string where 'Hello, world!' in (?, ?, ?, ?, ?, ?, ?)",
|
||||
string, // make sure we don't actually take ownership here
|
||||
&string[..],
|
||||
Some(&string),
|
||||
Some(&string[..]),
|
||||
Option::<String>::None,
|
||||
string.clone(),
|
||||
tuple.0 // make sure we're not trying to move out of a field expression
|
||||
)
|
||||
.fetch_one(&mut conn)
|
||||
.await?;
|
||||
|
||||
assert_eq!(result.string, string);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[sqlx_macros::test]
|
||||
async fn macro_select_from_view() -> anyhow::Result<()> {
|
||||
let mut conn = new::<Sqlite>().await?;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user