grafbase_sql_ast/ast/
values.rs

1use crate::ast::Row;
2
3/// An in-memory temporary table. Can be used in some of the databases in a
4/// place of an actual table. Doesn't work in MySQL 5.7.
5#[derive(Debug, Clone, Default, PartialEq)]
6pub struct Values<'a> {
7    pub(crate) rows: Vec<Row<'a>>,
8}
9
10impl<'a> Values<'a> {
11    /// Create a new empty in-memory set of values.
12    pub fn empty() -> Self {
13        Self { rows: Vec::new() }
14    }
15
16    /// Create a new in-memory set of values.
17    pub fn new(rows: Vec<Row<'a>>) -> Self {
18        Self { rows }
19    }
20
21    /// Create a new in-memory set of values with an allocated capacity.
22    pub fn with_capacity(capacity: usize) -> Self {
23        Self {
24            rows: Vec::with_capacity(capacity),
25        }
26    }
27
28    /// Add value to the temporary table.
29    pub fn push<T>(&mut self, row: T)
30    where
31        T: Into<Row<'a>>,
32    {
33        self.rows.push(row.into());
34    }
35
36    /// The number of rows in the in-memory table.
37    pub fn len(&self) -> usize {
38        self.rows.len()
39    }
40
41    /// True if has no rows.
42    pub fn is_empty(&self) -> bool {
43        self.len() == 0
44    }
45
46    pub fn row_len(&self) -> usize {
47        match self.rows.split_first() {
48            Some((row, _)) => row.len(),
49            None => 0,
50        }
51    }
52
53    pub fn flatten_row(self) -> Option<Row<'a>> {
54        let mut result = Row::with_capacity(self.len());
55
56        for mut row in self.rows.into_iter() {
57            match row.pop() {
58                Some(value) => result.push(value),
59                None => return None,
60            }
61        }
62
63        Some(result)
64    }
65}
66
67impl<'a, I, R> From<I> for Values<'a>
68where
69    I: Iterator<Item = R>,
70    R: Into<Row<'a>>,
71{
72    fn from(rows: I) -> Self {
73        Self {
74            rows: rows.map(|r| r.into()).collect(),
75        }
76    }
77}
78
79impl<'a> IntoIterator for Values<'a> {
80    type Item = Row<'a>;
81    type IntoIter = std::vec::IntoIter<Self::Item>;
82
83    fn into_iter(self) -> Self::IntoIter {
84        self.rows.into_iter()
85    }
86}