Skip to main content

ddb_core/engine/
row.rs

1// Row representation for query execution
2use crate::functions::Value;
3use std::collections::HashMap;
4
5/// A row of data with named columns
6#[derive(Debug, Clone)]
7pub struct Row {
8    columns: HashMap<String, Value>,
9}
10
11impl Row {
12    /// Create a new empty row
13    pub fn new() -> Self {
14        Row {
15            columns: HashMap::new(),
16        }
17    }
18
19    /// Create a row from column names and values
20    pub fn from_values(names: &[String], values: Vec<Value>) -> Self {
21        let mut row = Row::new();
22        for (name, value) in names.iter().zip(values.iter()) {
23            row.set(name, value.clone());
24        }
25        row
26    }
27
28    /// Get a column value by name
29    pub fn get(&self, name: &str) -> Option<&Value> {
30        self.columns.get(name)
31    }
32
33    /// Set a column value
34    pub fn set(&mut self, name: &str, value: Value) {
35        self.columns.insert(name.to_string(), value);
36    }
37
38    /// Get all column names
39    pub fn column_names(&self) -> Vec<String> {
40        self.columns.keys().cloned().collect()
41    }
42
43    /// Get all values in order of provided column names
44    pub fn values(&self, columns: &[String]) -> Vec<Value> {
45        columns
46            .iter()
47            .map(|name| self.get(name).cloned().unwrap_or(Value::Null))
48            .collect()
49    }
50
51    /// Get all values as a HashMap
52    pub fn as_map(&self) -> &HashMap<String, Value> {
53        &self.columns
54    }
55
56    /// Number of columns in the row
57    pub fn len(&self) -> usize {
58        self.columns.len()
59    }
60
61    /// Check if row is empty
62    pub fn is_empty(&self) -> bool {
63        self.columns.is_empty()
64    }
65}
66
67impl Default for Row {
68    fn default() -> Self {
69        Self::new()
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_row_creation() {
79        let mut row = Row::new();
80        row.set("name", Value::String("John".to_string()));
81        row.set("age", Value::Integer(30));
82
83        assert_eq!(row.get("name"), Some(&Value::String("John".to_string())));
84        assert_eq!(row.get("age"), Some(&Value::Integer(30)));
85        assert_eq!(row.get("missing"), None);
86    }
87
88    #[test]
89    fn test_row_from_values() {
90        let names = vec!["id".to_string(), "name".to_string()];
91        let values = vec![Value::Integer(1), Value::String("Alice".to_string())];
92        let row = Row::from_values(&names, values);
93
94        assert_eq!(row.get("id"), Some(&Value::Integer(1)));
95        assert_eq!(row.get("name"), Some(&Value::String("Alice".to_string())));
96    }
97}