Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide an option to bind values to each separate statement in a batch #108

Open
havaker opened this issue Nov 11, 2020 · 4 comments
Open
Labels
Milestone

Comments

@havaker
Copy link
Contributor

havaker commented Nov 11, 2020

While using current batch API, it is easy to encounter the problem of statements/values count mismatch. To avoid it, we need to provide an option to bind values to each separate statement in a batch.

New batch API should support:

  • Binding values to each separate statement in a batch
  • Modifying statement's values between batch executions
@altanozlu
Copy link
Contributor

is there any news about it ?

@psarna
Copy link
Contributor

psarna commented May 17, 2021

This issue is currently in a "pull requests welcome" state. It's generally on a roadmap, but the team is currently focused on providing performance benchmarks.

@krzysztofgal
Copy link

If someone needs func. like that - it is quite easy to impl according to usecase.

use super::{BatchValues, ScyllaError};
use scylla::batch::Batch;
use scylla::frame::value::SerializedValues;
use scylla::prepared_statement::PreparedStatement;

pub struct BatchPrepare {
    batch: Batch,
    values: Vec<SerializedValues>,
    stmt_count: u32,
}

impl BatchPrepare {
    pub fn new() -> Self {
        Self {
            batch: Batch::default(),
            values: Vec::new(),
            stmt_count: 0,
        }
    }

    pub fn take(mut self) -> (Batch, Vec<SerializedValues>) {
        let batch = std::mem::take(&mut self.batch);
        let values = std::mem::take(&mut self.values);
        self.stmt_count = 0;
        (batch, values)
    }

    pub fn add_batch_stmt(&mut self, prepared_statement: PreparedStatement) {
        self.batch.append_statement(prepared_statement);
        self.stmt_count += 1;
    }

    pub fn add_values(&mut self, values: impl BatchValues) -> Result<(), ScyllaError> {
        let v = values.as_batch_values()?;
        self.values.push(v);
        Ok(())
    }

    pub fn is_empty(&self) -> bool {
        self.stmt_count == 0
    }
}
use super::ScyllaError;
use scylla::frame::value::{SerializedValues, Value, ValueList};

fn add_value(s: &mut SerializedValues, val: &impl Value) -> Result<(), ScyllaError> {
    s.add_value(val)
        .map_err(|e| ScyllaError::Internal(e.into()))
}

pub trait BatchValues {
    fn as_batch_values(&self) -> Result<SerializedValues, ScyllaError>;
}

impl<T: ValueList> BatchValues for &T {
    fn as_batch_values(&self) -> Result<SerializedValues, ScyllaError> {
        let s = <T as ValueList>::serialized(self).map_err(|e| ScyllaError::Internal(e.into()))?;
        Ok(s.into_owned())
    }
}

macro_rules! impl_batch_tuple {
    ( $($Ti:ident),* ; $($FieldI:tt),*) => {
        impl<$($Ti),+> BatchValues for ($($Ti,)+)
            where
                $($Ti: Value),+
        {
            fn as_batch_values(&self) -> Result<SerializedValues, ScyllaError> {
                let mut s = SerializedValues::new();
                $(
                    add_value(&mut s, &self.$FieldI)?;
                )*
                Ok(s)
            }
        }
    }
}

impl_batch_tuple!(T0; 0);
impl_batch_tuple!(T0, T1; 0, 1);
impl_batch_tuple!(T0, T1, T2; 0, 1, 2);
impl_batch_tuple!(T0, T1, T2, T3; 0, 1, 2, 3);
impl_batch_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
impl_batch_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);

@Lorak-mmk Lorak-mmk self-assigned this Nov 15, 2023
@wprzytula
Copy link
Collaborator

Ref: #941

@wprzytula wprzytula added this to the 0.15.0 milestone May 14, 2024
@wprzytula wprzytula added the enhancement New feature or request label May 14, 2024
@Lorak-mmk Lorak-mmk removed their assignment Jul 31, 2024
@wprzytula wprzytula modified the milestones: 0.16.0, 2.0.0 Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants