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;
8
9pub trait TableGenerator: Send + Sync {
11 fn name(&self) -> &str;
13
14 fn columns(&self) -> Vec<DataColumn>;
16
17 fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>>;
20
21 fn description(&self) -> &str;
23
24 fn arg_count(&self) -> usize;
26}
27
28pub struct GeneratorRegistry {
30 generators: std::collections::HashMap<String, Box<dyn TableGenerator>>,
31}
32
33impl GeneratorRegistry {
34 pub fn new() -> Self {
35 let mut registry = Self {
36 generators: std::collections::HashMap::new(),
37 };
38 registry.register_default_generators();
39 registry
40 }
41
42 fn register_default_generators(&mut self) {
43 use math_generators::{Collatz, Factorials, PascalTriangle, Squares, TriangularNumbers};
44 use prime_generators::{Fibonacci, GeneratePrimes, PrimeFactors};
45 use random_generators::{GenerateUUIDs, RandomFloats, RandomIntegers};
46
47 self.register(Box::new(GeneratePrimes));
49 self.register(Box::new(PrimeFactors));
50 self.register(Box::new(Fibonacci));
51
52 self.register(Box::new(Collatz));
54 self.register(Box::new(PascalTriangle));
55 self.register(Box::new(TriangularNumbers));
56 self.register(Box::new(Squares));
57 self.register(Box::new(Factorials));
58
59 self.register(Box::new(RandomIntegers));
61 self.register(Box::new(RandomFloats));
62 self.register(Box::new(GenerateUUIDs));
63 }
64
65 pub fn register(&mut self, generator: Box<dyn TableGenerator>) {
66 self.generators
67 .insert(generator.name().to_uppercase(), generator);
68 }
69
70 pub fn get(&self, name: &str) -> Option<&Box<dyn TableGenerator>> {
71 self.generators.get(&name.to_uppercase())
72 }
73
74 pub fn list(&self) -> Vec<&str> {
75 let mut names: Vec<&str> = self.generators.keys().map(|s| s.as_str()).collect();
76 names.sort();
77 names
78 }
79
80 pub fn list_generators_formatted(&self) -> String {
81 let mut output = String::new();
82 output.push_str("=== Available Generator Functions ===\n\n");
83
84 let mut math_gens = Vec::new();
86 let mut random_gens = Vec::new();
87 let mut utility_gens = Vec::new();
88
89 for (name, gen) in &self.generators {
90 let entry = format!(" {} - {}", name, gen.description());
91
92 if name.starts_with("RANDOM_") {
93 random_gens.push(entry);
94 } else if name == "GENERATE_UUID" {
95 utility_gens.push(entry);
96 } else {
97 math_gens.push(entry);
98 }
99 }
100
101 if !math_gens.is_empty() {
102 math_gens.sort();
103 output.push_str("Mathematical Generators:\n");
104 for entry in math_gens {
105 output.push_str(&format!("{}\n", entry));
106 }
107 output.push('\n');
108 }
109
110 if !random_gens.is_empty() {
111 random_gens.sort();
112 output.push_str("Random Generators:\n");
113 for entry in random_gens {
114 output.push_str(&format!("{}\n", entry));
115 }
116 output.push('\n');
117 }
118
119 if !utility_gens.is_empty() {
120 utility_gens.sort();
121 output.push_str("Utility Generators:\n");
122 for entry in utility_gens {
123 output.push_str(&format!("{}\n", entry));
124 }
125 output.push('\n');
126 }
127
128 output.push_str("Use: SELECT * FROM <generator>(<args>)\n");
129 output.push_str("Example: SELECT * FROM GENERATE_PRIMES(100)\n");
130 output
131 }
132
133 pub fn get_generator_help(&self, name: &str) -> Option<String> {
134 self.generators.get(&name.to_uppercase()).map(|gen| {
135 let mut help = String::new();
136 help.push_str(&format!("=== {} ===\n\n", name.to_uppercase()));
137 help.push_str(&format!("Description: {}\n", gen.description()));
138 help.push_str(&format!(
139 "Arguments: {} argument(s) expected\n",
140 gen.arg_count()
141 ));
142 help.push_str("\nColumns:\n");
143 for col in gen.columns() {
144 help.push_str(&format!(" - {}\n", col.name));
145 }
146 help.push_str("\nExample:\n");
147 help.push_str(&format!(" SELECT * FROM {}(", name.to_uppercase()));
148
149 match name.to_uppercase().as_str() {
151 "GENERATE_PRIMES" => help.push_str("100"),
152 "FIBONACCI" => help.push_str("20"),
153 "PRIME_FACTORS" => help.push_str("1260"),
154 "COLLATZ" => help.push_str("7"),
155 "PASCAL_TRIANGLE" => help.push_str("5"),
156 "TRIANGULAR" | "SQUARES" | "FACTORIALS" => help.push_str("10"),
157 "RANDOM_INT" => help.push_str("10, 1, 100, 42"),
158 "RANDOM_FLOAT" => help.push_str("10, 0, 1, 42"),
159 "GENERATE_UUID" => help.push_str("5"),
160 _ => help.push_str("..."),
161 }
162 help.push_str(");\n");
163 help
164 })
165 }
166}
167
168pub fn create_single_column_table(
170 name: &str,
171 column_name: &str,
172 values: Vec<DataValue>,
173) -> Arc<DataTable> {
174 let mut table = DataTable::new(name);
175 table.add_column(DataColumn::new(column_name));
176
177 for value in values {
178 table.add_row(DataRow::new(vec![value])).unwrap();
179 }
180
181 Arc::new(table)
182}
183
184pub fn create_two_column_table(
186 name: &str,
187 col1_name: &str,
188 col2_name: &str,
189 rows: Vec<(DataValue, DataValue)>,
190) -> Arc<DataTable> {
191 let mut table = DataTable::new(name);
192 table.add_column(DataColumn::new(col1_name));
193 table.add_column(DataColumn::new(col2_name));
194
195 for (val1, val2) in rows {
196 table.add_row(DataRow::new(vec![val1, val2])).unwrap();
197 }
198
199 Arc::new(table)
200}