dataforge/db/
mod.rs

1//! 数据库相关模块
2//! 
3//! 包含数据库填充、Schema解析、类型映射等功能
4
5#[cfg(feature = "database")]
6use sqlx::{Database, Pool};
7use serde_json::Value;
8use crate::error::Result;
9use crate::generation::DataForge;
10
11// 重新导出schema模块的类型
12pub mod schema;
13pub use schema::{TableSchema, FieldSchema, DataType, SchemaParser};
14
15/// 数据库适配器 Trait
16pub trait DatabaseAdapter {
17    /// 自动推断表结构
18    fn infer_schema(&self) -> Result<TableSchema>;
19    
20    /// 批量数据插入(支持事务回滚)
21    fn bulk_insert(&self, table: &str, data: Vec<Value>) -> Result<usize>;
22    
23    /// 类型转换系统
24    fn type_mapping(&self, rust_type: &str) -> String;
25}
26
27/// 现代化的数据库填充器(支持泛型数据库类型)
28#[cfg(feature = "database")]
29pub struct GenericDatabaseForge<DB: Database> {
30    #[allow(dead_code)]
31    pool: Pool<DB>,
32    tables: Vec<TableConfig>,
33    schema_parser: SchemaParser,
34}
35
36/// 简化的数据库填充器(不依赖sqlx)
37pub struct SimpleDatabaseForge {
38    #[allow(dead_code)]
39    forge: DataForge,
40    connection_string: String,
41    batch_size: usize,
42    schema_parser: SchemaParser,
43}
44
45/// 表配置
46pub struct TableConfig {
47    pub name: String,
48    pub count: usize,
49    pub fields: Vec<FieldConfig>,
50}
51
52/// 字段配置
53pub struct FieldConfig {
54    pub name: String,
55    pub generator: Box<dyn Fn() -> Value + Send + Sync>,
56}
57
58#[cfg(feature = "database")]
59impl<DB: Database> GenericDatabaseForge<DB> {
60    /// 创建新的数据库填充器
61    pub fn new(pool: Pool<DB>) -> Self {
62        Self {
63            pool,
64            tables: Vec::new(),
65            schema_parser: SchemaParser::new(),
66        }
67    }
68
69    /// 添加表配置
70    pub fn table<F>(mut self, name: &str, count: usize, config: F) -> Self
71    where
72        F: FnOnce(&mut TableBuilder) -> &mut TableBuilder,
73    {
74        let mut builder = TableBuilder::new(name.to_string());
75        config(&mut builder);
76        self.tables.push(builder.build(count));
77        self
78    }
79
80    /// 执行数据填充
81    pub async fn fill(&self) -> Result<()> {
82        for table in &self.tables {
83            self.fill_table(table).await?;
84        }
85        Ok(())
86    }
87
88    /// 填充单个表
89    async fn fill_table(&self, _table: &TableConfig) -> Result<()> {
90        // 这里需要根据具体的数据库类型实现。由于这是一个通用实现,我们只提供接口
91        todo!("Database-specific implementation needed")
92    }
93
94    /// 获取Schema解析器
95    pub fn schema_parser(&self) -> &SchemaParser {
96        &self.schema_parser
97    }
98
99    /// 获取可变的Schema解析器
100    pub fn schema_parser_mut(&mut self) -> &mut SchemaParser {
101        &mut self.schema_parser
102    }
103}
104
105impl SimpleDatabaseForge {
106    /// 创建新的简化数据库填充器
107    pub fn new(connection_string: &str) -> Self {
108        Self {
109            forge: DataForge::default(),
110            connection_string: connection_string.to_string(),
111            batch_size: 1000,
112            schema_parser: SchemaParser::new(),
113        }
114    }
115
116    /// 设置批次大小
117    pub fn batch_size(mut self, size: usize) -> Self {
118        self.batch_size = size;
119        self
120    }
121
122    /// 配置表填充
123    pub fn table<F>(self, table_name: &str, count: usize, config: F) -> TableFillConfig
124    where
125        F: FnOnce(&mut TableBuilder) -> &mut TableBuilder,
126    {
127        let mut builder = TableBuilder::new(table_name.to_string());
128        config(&mut builder);
129        
130        TableFillConfig {
131            forge: self,
132            table_name: table_name.to_string(),
133            count,
134            fields: builder.build_simple(),
135        }
136    }
137
138    /// 获取Schema解析器
139    pub fn schema_parser(&self) -> &SchemaParser {
140        &self.schema_parser
141    }
142
143    /// 获取可变的Schema解析器
144    pub fn schema_parser_mut(&mut self) -> &mut SchemaParser {
145        &mut self.schema_parser
146    }
147
148    /// 获取连接字符串
149    pub fn connection_string(&self) -> &str {
150        &self.connection_string
151    }
152
153    /// 获取当前批次大小
154    pub fn get_batch_size(&self) -> usize {
155        self.batch_size
156    }
157}
158
159/// 表填充配置
160pub struct TableFillConfig {
161    #[allow(dead_code)]
162    forge: SimpleDatabaseForge,
163    table_name: String,
164    count: usize,
165    fields: Vec<(String, Box<dyn Fn() -> Value + Send + Sync>)>,
166}
167
168impl TableFillConfig {
169    /// 执行填充
170    #[cfg(feature = "database")]
171    pub async fn fill(self) -> Result<usize> {
172        // 这里应该实现实际的数据库连接和插入逻辑
173        // 由于这是示例,我们只返回模拟结果
174        println!("模拟填充表 {} 共 {} 条记录", self.table_name, self.count);
175        
176        // 生成数据
177        for i in 0..self.count.min(5) { // 只打印前5条作为示例
178            let mut record = serde_json::Map::new();
179            for (field_name, generator) in &self.fields {
180                record.insert(field_name.clone(), generator());
181            }
182            println!("记录 {}: {}", i + 1, serde_json::to_string_pretty(&record)?);
183        }
184        
185        Ok(self.count)
186    }
187
188    /// 同步版本的填充
189    pub fn fill_sync(self) -> Result<usize> {
190        println!("填充表 {} 共 {} 条记录", self.table_name, self.count);
191        
192        // 生成数据
193        for i in 0..self.count.min(5) { // 只打印前5条作为示例
194            let mut record = serde_json::Map::new();
195            for (field_name, generator) in &self.fields {
196                record.insert(field_name.clone(), generator());
197            }
198            println!("记录 {}: {}", i + 1, serde_json::to_string_pretty(&record)?);
199        }
200        
201        Ok(self.count)
202    }
203
204    /// 获取表名
205    pub fn table_name(&self) -> &str {
206        &self.table_name
207    }
208
209    /// 获取记录数量
210    pub fn count(&self) -> usize {
211        self.count
212    }
213
214    /// 获取字段配置
215    pub fn fields(&self) -> &Vec<(String, Box<dyn Fn() -> Value + Send + Sync>)> {
216        &self.fields
217    }
218}
219
220/// 表构建器
221pub struct TableBuilder {
222    name: String,
223    fields: Vec<FieldConfig>,
224}
225
226impl TableBuilder {
227    fn new(name: String) -> Self {
228        Self {
229            name,
230            fields: Vec::new(),
231        }
232    }
233
234    /// 添加字段
235    pub fn field<F>(&mut self, name: &str, generator: F) -> &mut Self
236    where
237        F: Fn() -> Value + Send + Sync + 'static,
238    {
239        self.fields.push(FieldConfig {
240            name: name.to_string(),
241            generator: Box::new(generator),
242        });
243        self
244    }
245
246    /// 构建表配置
247    fn build(self, count: usize) -> TableConfig {
248        TableConfig {
249            name: self.name,
250            count,
251            fields: self.fields,
252        }
253    }
254
255    /// 构建简单表配置(用于SimpleDatabaseForge)
256    fn build_simple(self) -> Vec<(String, Box<dyn Fn() -> Value + Send + Sync>)> {
257        self.fields.into_iter().map(|field| (field.name, field.generator)).collect()
258    }
259}
260
261// 类型别名,保持向后兼容
262// 默认的DatabaseForge指向简化版本
263pub type DatabaseForge = SimpleDatabaseForge;
264
265/// MySQL 数据库填充器(泛型版本)
266#[cfg(feature = "database")]
267pub type MySqlForge = GenericDatabaseForge<sqlx::MySql>;
268
269/// PostgreSQL 数据库填充器(泛型版本)
270#[cfg(feature = "database")]
271pub type PostgresForge = GenericDatabaseForge<sqlx::Postgres>;
272
273/// SQLite 数据库填充器(泛型版本)
274#[cfg(feature = "database")]
275pub type SqliteForge = GenericDatabaseForge<sqlx::Sqlite>;
276
277#[cfg(test)]
278mod tests {
279    use super::*;
280
281    #[test]
282    fn test_simple_database_forge() {
283        let forge = SimpleDatabaseForge::new("sqlite://test.db");
284        assert_eq!(forge.connection_string, "sqlite://test.db");
285        assert_eq!(forge.batch_size, 1000);
286    }
287
288    #[test]
289    fn test_table_builder() {
290        let mut builder = TableBuilder::new("users".to_string());
291        builder
292            .field("id", || Value::String("test".to_string()))
293            .field("name", || Value::String("test_name".to_string()));
294
295        let table = builder.build(100);
296        assert_eq!(table.name, "users");
297        assert_eq!(table.count, 100);
298        assert_eq!(table.fields.len(), 2);
299    }
300
301    #[test]
302    fn test_schema_parser_integration() {
303        let forge = SimpleDatabaseForge::new("test://db");
304        let parser = forge.schema_parser();
305        
306        // 测试Schema解析器是否正确初始化
307        // 通过尝试推断一个简单的类型来验证解析器工作正常
308        let json_schema = serde_json::json!({
309            "title": "Test",
310            "properties": {
311                "id": {"type": "integer"}
312            }
313        });
314        
315        let result = parser.infer_from_json(&json_schema);
316        assert!(result.is_ok());
317    }
318}