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