sql_cli/data/
virtual_table_generator.rs1use anyhow::{anyhow, Result};
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::data::datatable::{DataColumn, DataRow, DataTable, DataType, DataValue};
6
7pub struct VirtualTableGenerator;
8
9impl VirtualTableGenerator {
10 pub fn generate_range(
11 start: i64,
12 end: i64,
13 step: Option<i64>,
14 column_name: Option<String>,
15 ) -> Result<Arc<DataTable>> {
16 let step = step.unwrap_or(1);
17 let column_name = column_name.unwrap_or_else(|| "value".to_string());
18
19 if step == 0 {
20 return Err(anyhow!("RANGE step cannot be zero"));
21 }
22
23 if (step > 0 && start > end) || (step < 0 && start < end) {
24 return Err(anyhow!(
25 "RANGE parameters invalid: start={}, end={}, step={}",
26 start,
27 end,
28 step
29 ));
30 }
31
32 let mut table = DataTable::new("range_table");
33
34 let column = DataColumn {
35 name: column_name,
36 data_type: DataType::Integer,
37 nullable: false,
38 unique_values: Some(0),
39 null_count: 0,
40 metadata: HashMap::new(),
41 };
42 table.add_column(column);
43
44 let mut current = start;
45 while (step > 0 && current <= end) || (step < 0 && current >= end) {
46 let row = DataRow {
47 values: vec![DataValue::Integer(current)],
48 };
49 table.add_row(row);
50 current += step;
51 }
52
53 Ok(Arc::new(table))
54 }
55
56 pub fn generate_series(count: i64, start: Option<i64>) -> Result<Arc<DataTable>> {
57 let start = start.unwrap_or(1);
58 Self::generate_range(start, start + count - 1, Some(1), Some("index".to_string()))
59 }
60
61 pub fn generate_split(
63 text: &str,
64 delimiter: Option<&str>,
65 column_name: Option<String>,
66 ) -> Result<Arc<DataTable>> {
67 let delimiter = delimiter.unwrap_or(" ");
68 let column_name = column_name.unwrap_or_else(|| "value".to_string());
69
70 let mut table = DataTable::new("split_table");
71
72 let column = DataColumn {
73 name: column_name,
74 data_type: DataType::String,
75 nullable: false,
76 unique_values: Some(0),
77 null_count: 0,
78 metadata: HashMap::new(),
79 };
80 table.add_column(column);
81
82 let index_column = DataColumn {
84 name: "index".to_string(),
85 data_type: DataType::Integer,
86 nullable: false,
87 unique_values: Some(0),
88 null_count: 0,
89 metadata: HashMap::new(),
90 };
91 table.add_column(index_column);
92
93 let parts: Vec<String> = if delimiter.is_empty() {
95 text.chars().map(|c| c.to_string()).collect()
97 } else {
98 text.split(delimiter).map(|s| s.to_string()).collect()
99 };
100
101 for (i, part) in parts.iter().enumerate() {
102 if part.is_empty() && delimiter != "" {
104 continue;
105 }
106
107 let row = DataRow {
108 values: vec![
109 DataValue::String(part.clone()),
110 DataValue::Integer((i + 1) as i64),
111 ],
112 };
113 table.add_row(row);
114 }
115
116 Ok(Arc::new(table))
117 }
118}