sql_cli/sql/generators/
mod.rs1use crate::data::datatable::{DataColumn, DataRow, DataTable, DataValue};
2use anyhow::Result;
3use std::sync::Arc;
4
5pub mod literal_generators;
6pub mod math_generators;
7pub mod prime_generators;
8pub mod random_generators;
9pub mod sequence_generators;
10pub mod string_generators;
11
12pub trait TableGenerator: Send + Sync {
14 fn name(&self) -> &str;
16
17 fn columns(&self) -> Vec<DataColumn>;
19
20 fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>>;
23
24 fn description(&self) -> &str;
26
27 fn arg_count(&self) -> usize;
29}
30
31pub struct GeneratorRegistry {
33 generators: std::collections::HashMap<String, Box<dyn TableGenerator>>,
34}
35
36impl GeneratorRegistry {
37 pub fn new() -> Self {
38 let mut registry = Self {
39 generators: std::collections::HashMap::new(),
40 };
41 registry.register_default_generators();
42 registry
43 }
44
45 fn register_default_generators(&mut self) {
46 use literal_generators::{Array, Values};
47 use math_generators::{Collatz, Factorials, PascalTriangle, Squares, TriangularNumbers};
48 use prime_generators::{Fibonacci, GeneratePrimes, PrimeFactors};
49 use random_generators::{GenerateUUIDs, RandomFloats, RandomIntegers};
50 use sequence_generators::{Dates, Range, Series};
51 use string_generators::{Chars, Lines, Split, Tokenize};
52
53 self.register(Box::new(Values));
55 self.register(Box::new(Array));
56
57 self.register(Box::new(Range));
59 self.register(Box::new(Series));
60 self.register(Box::new(Dates));
61
62 self.register(Box::new(Split));
64 self.register(Box::new(Tokenize));
65 self.register(Box::new(Chars));
66 self.register(Box::new(Lines));
67
68 self.register(Box::new(GeneratePrimes));
70 self.register(Box::new(PrimeFactors));
71 self.register(Box::new(Fibonacci));
72
73 self.register(Box::new(Collatz));
75 self.register(Box::new(PascalTriangle));
76 self.register(Box::new(TriangularNumbers));
77 self.register(Box::new(Squares));
78 self.register(Box::new(Factorials));
79
80 self.register(Box::new(RandomIntegers));
82 self.register(Box::new(RandomFloats));
83 self.register(Box::new(GenerateUUIDs));
84 }
85
86 pub fn register(&mut self, generator: Box<dyn TableGenerator>) {
87 self.generators
88 .insert(generator.name().to_uppercase(), generator);
89 }
90
91 pub fn get(&self, name: &str) -> Option<&Box<dyn TableGenerator>> {
92 self.generators.get(&name.to_uppercase())
93 }
94
95 pub fn list(&self) -> Vec<&str> {
96 let mut names: Vec<&str> = self.generators.keys().map(|s| s.as_str()).collect();
97 names.sort();
98 names
99 }
100
101 pub fn list_generators_formatted(&self) -> String {
102 let mut output = String::new();
103 output.push_str("=== Available Generator Functions ===\n\n");
104
105 let mut sequence_gens = Vec::new();
107 let mut string_gens = Vec::new();
108 let mut math_gens = Vec::new();
109 let mut random_gens = Vec::new();
110 let mut utility_gens = Vec::new();
111
112 for (name, gen) in &self.generators {
113 let entry = format!(" {} - {}", name, gen.description());
114
115 if name == "RANGE" || name == "SERIES" || name == "DATES" {
116 sequence_gens.push(entry);
117 } else if name == "SPLIT" || name == "TOKENIZE" || name == "CHARS" || name == "LINES" {
118 string_gens.push(entry);
119 } else if name.starts_with("RANDOM_") {
120 random_gens.push(entry);
121 } else if name == "GENERATE_UUID" {
122 utility_gens.push(entry);
123 } else {
124 math_gens.push(entry);
125 }
126 }
127
128 if !sequence_gens.is_empty() {
129 sequence_gens.sort();
130 output.push_str("Sequence Generators:\n");
131 for entry in sequence_gens {
132 output.push_str(&format!("{}\n", entry));
133 }
134 output.push('\n');
135 }
136
137 if !string_gens.is_empty() {
138 string_gens.sort();
139 output.push_str("String Generators:\n");
140 for entry in string_gens {
141 output.push_str(&format!("{}\n", entry));
142 }
143 output.push('\n');
144 }
145
146 if !math_gens.is_empty() {
147 math_gens.sort();
148 output.push_str("Mathematical Generators:\n");
149 for entry in math_gens {
150 output.push_str(&format!("{}\n", entry));
151 }
152 output.push('\n');
153 }
154
155 if !random_gens.is_empty() {
156 random_gens.sort();
157 output.push_str("Random Generators:\n");
158 for entry in random_gens {
159 output.push_str(&format!("{}\n", entry));
160 }
161 output.push('\n');
162 }
163
164 if !utility_gens.is_empty() {
165 utility_gens.sort();
166 output.push_str("Utility Generators:\n");
167 for entry in utility_gens {
168 output.push_str(&format!("{}\n", entry));
169 }
170 output.push('\n');
171 }
172
173 output.push_str("Use: SELECT * FROM <generator>(<args>)\n");
174 output.push_str("Example: SELECT * FROM GENERATE_PRIMES(100)\n");
175 output
176 }
177
178 pub fn get_generator_help(&self, name: &str) -> Option<String> {
179 self.generators.get(&name.to_uppercase()).map(|gen| {
180 let mut help = String::new();
181 help.push_str(&format!("=== {} ===\n\n", name.to_uppercase()));
182 help.push_str(&format!("Description: {}\n", gen.description()));
183 help.push_str(&format!(
184 "Arguments: {} argument(s) expected\n",
185 gen.arg_count()
186 ));
187 help.push_str("\nColumns:\n");
188 for col in gen.columns() {
189 help.push_str(&format!(" - {}\n", col.name));
190 }
191 help.push_str("\nExample:\n");
192 help.push_str(&format!(" SELECT * FROM {}(", name.to_uppercase()));
193
194 match name.to_uppercase().as_str() {
196 "GENERATE_PRIMES" => help.push_str("100"),
197 "FIBONACCI" => help.push_str("20"),
198 "PRIME_FACTORS" => help.push_str("1260"),
199 "COLLATZ" => help.push_str("7"),
200 "PASCAL_TRIANGLE" => help.push_str("5"),
201 "TRIANGULAR" | "SQUARES" | "FACTORIALS" => help.push_str("10"),
202 "RANDOM_INT" => help.push_str("10, 1, 100, 42"),
203 "RANDOM_FLOAT" => help.push_str("10, 0, 1, 42"),
204 "GENERATE_UUID" => help.push_str("5"),
205 _ => help.push_str("..."),
206 }
207 help.push_str(");\n");
208 help
209 })
210 }
211}
212
213pub fn create_single_column_table(
215 name: &str,
216 column_name: &str,
217 values: Vec<DataValue>,
218) -> Arc<DataTable> {
219 let mut table = DataTable::new(name);
220 table.add_column(DataColumn::new(column_name));
221
222 for value in values {
223 table.add_row(DataRow::new(vec![value])).unwrap();
224 }
225
226 Arc::new(table)
227}
228
229pub fn create_two_column_table(
231 name: &str,
232 col1_name: &str,
233 col2_name: &str,
234 rows: Vec<(DataValue, DataValue)>,
235) -> Arc<DataTable> {
236 let mut table = DataTable::new(name);
237 table.add_column(DataColumn::new(col1_name));
238 table.add_column(DataColumn::new(col2_name));
239
240 for (val1, val2) in rows {
241 table.add_row(DataRow::new(vec![val1, val2])).unwrap();
242 }
243
244 Arc::new(table)
245}