refactor: allow non-Send adding to arguments crate-local

This commit is contained in:
Ryan Leckey 2020-06-27 04:06:22 -07:00
parent eb26e9f557
commit b7ec7bbd3e
6 changed files with 64 additions and 49 deletions

View file

@ -58,18 +58,10 @@ impl MssqlArguments {
self.ordinal += arguments.ordinal;
self.data.append(&mut arguments.data);
}
}
impl<'q> Arguments<'q> for MssqlArguments {
type Database = Mssql;
fn reserve(&mut self, _additional: usize, size: usize) {
self.data.reserve(size + 10); // est. 4 chars for name, 1 for status, 1 for TYPE_INFO
}
fn add<T>(&mut self, value: T)
pub(crate) fn add<'q, T>(&mut self, value: T)
where
T: 'q + Encode<'q, Self::Database> + Type<Mssql>,
T: Encode<'q, Mssql> + Type<Mssql>,
{
let ty = value.produces().unwrap_or_else(T::type_info);
@ -109,3 +101,18 @@ impl<'q> Arguments<'q> for MssqlArguments {
ty.0.put_value(data, value); // [ParamLenData]
}
}
impl<'q> Arguments<'q> for MssqlArguments {
type Database = Mssql;
fn reserve(&mut self, _additional: usize, size: usize) {
self.data.reserve(size + 10); // est. 4 chars for name, 1 for status, 1 for TYPE_INFO
}
fn add<T>(&mut self, value: T)
where
T: 'q + Encode<'q, Self::Database> + Type<Mssql>,
{
self.add(value)
}
}

View file

@ -1,5 +1,3 @@
use std::ops::{Deref, DerefMut};
use crate::arguments::Arguments;
use crate::encode::{Encode, IsNull};
use crate::mysql::{MySql, MySqlTypeInfo};
@ -13,6 +11,23 @@ pub struct MySqlArguments {
pub(crate) null_bitmap: Vec<u8>,
}
impl MySqlArguments {
pub(crate) fn add<'q, T>(&mut self, value: T)
where
T: Encode<'q, MySql> + Type<MySql>,
{
let ty = value.produces().unwrap_or_else(T::type_info);
let index = self.types.len();
self.types.push(ty);
self.null_bitmap.resize((index / 8) + 1, 0);
if let IsNull::Yes = value.encode(&mut self.values) {
self.null_bitmap[index / 8] |= (1 << (index % 8)) as u8;
}
}
}
impl<'q> Arguments<'q> for MySqlArguments {
type Database = MySql;
@ -25,28 +40,6 @@ impl<'q> Arguments<'q> for MySqlArguments {
where
T: Encode<'q, Self::Database> + Type<Self::Database>,
{
let ty = value.produces().unwrap_or_else(T::type_info);
let index = self.types.len();
self.types.push(ty);
self.null_bitmap.resize((index / 8) + 1, 0);
if let IsNull::Yes = value.encode(self) {
self.null_bitmap[index / 8] |= (1 << (index % 8)) as u8;
}
}
}
impl Deref for MySqlArguments {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.values
}
}
impl DerefMut for MySqlArguments {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.values
self.add(value)
}
}

View file

@ -18,7 +18,7 @@ impl<'q> Encode<'_, Capabilities> for Execute<'q> {
buf.push(0); // NO_CURSOR
buf.extend(&0_u32.to_le_bytes()); // iterations (always 1): int<4>
if !self.arguments.is_empty() {
if !self.arguments.values.is_empty() {
buf.extend(&*self.arguments.null_bitmap);
buf.push(1); // send type to server

View file

@ -31,6 +31,20 @@ pub struct PgArguments {
pub(crate) buffer: PgArgumentBuffer,
}
impl PgArguments {
pub(crate) fn add<'q, T>(&mut self, value: T)
where
T: Encode<'q, Postgres> + Type<Postgres>,
{
// remember the type information for this value
self.types
.push(value.produces().unwrap_or_else(T::type_info));
// encode the value into our buffer
self.buffer.encode(value);
}
}
impl<'q> Arguments<'q> for PgArguments {
type Database = Postgres;
@ -43,12 +57,7 @@ impl<'q> Arguments<'q> for PgArguments {
where
T: Encode<'q, Self::Database> + Type<Self::Database>,
{
// remember the type information for this value
self.types
.push(value.produces().unwrap_or_else(T::type_info));
// encode the value into our buffer
self.buffer.encode(value);
self.add(value)
}
}

View file

@ -5,7 +5,6 @@ use std::sync::Arc;
use futures_util::{stream, StreamExt, TryStreamExt};
use hashbrown::HashMap;
use crate::arguments::Arguments;
use crate::describe::Column;
use crate::error::Error;
use crate::ext::ustr::UStr;
@ -22,8 +21,6 @@ impl PgConnection {
&mut self,
desc: Option<RowDescription>,
should_fetch: bool,
// columns: &mut Vec<PgColumn>,
// column_names: &mut HashMap<UStr, usize>,
) -> Result<(), Error> {
let mut columns = Vec::new();
let mut column_names = HashMap::new();

View file

@ -24,6 +24,17 @@ pub struct SqliteArguments<'q> {
pub(crate) values: Vec<SqliteArgumentValue<'q>>,
}
impl<'q> SqliteArguments<'q> {
pub(crate) fn add<T>(&mut self, value: T)
where
T: Encode<'q, Sqlite>,
{
if let IsNull::Yes = value.encode(&mut self.values) {
self.values.push(SqliteArgumentValue::Null);
}
}
}
impl<'q> Arguments<'q> for SqliteArguments<'q> {
type Database = Sqlite;
@ -33,11 +44,9 @@ impl<'q> Arguments<'q> for SqliteArguments<'q> {
fn add<T>(&mut self, value: T)
where
T: 'q + Encode<'q, Self::Database>,
T: Encode<'q, Self::Database>,
{
if let IsNull::Yes = value.encode(&mut self.values) {
self.values.push(SqliteArgumentValue::Null);
}
self.add(value)
}
}