Update src/server/csv_import_export.rs
This commit is contained in:
parent
61b8a6795c
commit
12364a7edd
@ -30,8 +30,8 @@ use crate::server::database::Database;
|
||||
/// Lock-free хэш-таблица для прогресса импорта
|
||||
/// Использует DashMap для атомарного доступа к данным прогресса
|
||||
struct LockFreeProgressMap {
|
||||
progress_data: DashMap<String, f64>,
|
||||
active_imports: AtomicUsize,
|
||||
progress_data: DashMap<String, f64>, // Данные прогресса по коллекциям
|
||||
active_imports: AtomicUsize, // Количество активных импортов
|
||||
}
|
||||
|
||||
impl LockFreeProgressMap {
|
||||
@ -74,14 +74,14 @@ impl LockFreeProgressMap {
|
||||
/// Менеджер CSV операций с lock-free архитектурой
|
||||
#[derive(Clone)]
|
||||
pub struct CsvManager {
|
||||
database: Arc<Database>,
|
||||
config: CsvConfig,
|
||||
import_progress: Arc<LockFreeProgressMap>,
|
||||
// Используем RwLock для буферизации, но без блокировок на операции
|
||||
import_buffer: Arc<RwLock<DashMap<String, Vec<Value>>>>,
|
||||
database: Arc<Database>, // Ссылка на базу данных
|
||||
config: CsvConfig, // Конфигурация CSV операций
|
||||
import_progress: Arc<LockFreeProgressMap>, // Прогресс импорта
|
||||
import_buffer: Arc<RwLock<DashMap<String, Vec<Value>>>>, // Буфер для импорта
|
||||
}
|
||||
|
||||
impl CsvManager {
|
||||
/// Создает новый менеджер CSV операций
|
||||
pub fn new(database: Arc<Database>, config: CsvConfig) -> Self {
|
||||
// Создаем директории для импорта и экспорта, если они не существуют
|
||||
let _ = std::fs::create_dir_all(&config.import_dir);
|
||||
@ -95,6 +95,7 @@ impl CsvManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Импортирует CSV файл в указанную коллекцию
|
||||
pub fn import_csv(&self, collection_name: &str, file_path: &str) -> Result<usize> {
|
||||
// Проверяем размер файла
|
||||
let metadata = std::fs::metadata(file_path)
|
||||
@ -143,6 +144,7 @@ impl CsvManager {
|
||||
|
||||
let mut document = serde_json::Map::new();
|
||||
|
||||
// Преобразуем каждое поле CSV в JSON значение
|
||||
for (i, field) in record.iter().enumerate() {
|
||||
let header = if i < headers.len() {
|
||||
&headers[i]
|
||||
@ -157,8 +159,8 @@ impl CsvManager {
|
||||
let json_value = Value::Object(document);
|
||||
buffer.push(json_value);
|
||||
|
||||
// Вставляем пачку записей при достижении лимита
|
||||
if buffer.len() >= 100 {
|
||||
// Вставляем пачку записей
|
||||
match self.insert_batch(collection_name, &buffer) {
|
||||
Ok(inserted) => {
|
||||
record_count += inserted;
|
||||
@ -170,6 +172,7 @@ impl CsvManager {
|
||||
}
|
||||
buffer.clear();
|
||||
|
||||
// Обновляем прогресс каждые 100 записей
|
||||
if record_count % 100 == 0 {
|
||||
println!("Imported {} records...", record_count);
|
||||
|
||||
@ -266,6 +269,7 @@ impl CsvManager {
|
||||
Value::String(field.to_string())
|
||||
}
|
||||
|
||||
/// Экспортирует коллекцию в CSV файл
|
||||
pub fn export_csv(&self, collection_name: &str, file_path: &str) -> Result<usize> {
|
||||
println!("Exporting collection '{}' to CSV file '{}'", collection_name, file_path);
|
||||
|
||||
@ -332,6 +336,7 @@ impl CsvManager {
|
||||
.map_err(|e| crate::common::FutriixError::CsvError(e.to_string()))?;
|
||||
record_count += 1;
|
||||
|
||||
// Отображаем прогресс каждые 100 записей
|
||||
if record_count % 100 == 0 {
|
||||
println!("Exported {} records...", record_count);
|
||||
}
|
||||
@ -363,11 +368,13 @@ impl CsvManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Получает прогресс импорта для указанной коллекции
|
||||
pub fn get_import_progress(&self, collection_name: &str) -> f64 {
|
||||
self.import_progress.get(collection_name)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
|
||||
/// Список доступных CSV файлов в директории импорта
|
||||
pub fn list_csv_files(&self) -> Result<Vec<String>> {
|
||||
let csv_dir = &self.config.import_dir;
|
||||
let mut csv_files = Vec::new();
|
||||
@ -390,6 +397,7 @@ impl CsvManager {
|
||||
Ok(csv_files)
|
||||
}
|
||||
|
||||
/// Полный путь к файлу импорта
|
||||
pub fn get_import_file_path(&self, file_name: &str) -> String {
|
||||
Path::new(&self.config.import_dir)
|
||||
.join(file_name)
|
||||
@ -397,6 +405,7 @@ impl CsvManager {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Полный путь к файлу экспорта
|
||||
pub fn get_export_file_path(&self, file_name: &str) -> String {
|
||||
Path::new(&self.config.export_dir)
|
||||
.join(file_name)
|
||||
@ -404,11 +413,13 @@ impl CsvManager {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Проверяет существование файла
|
||||
pub fn file_exists(&self, file_path: &str) -> bool {
|
||||
Path::new(file_path).exists()
|
||||
}
|
||||
|
||||
/// Количество активных импортов
|
||||
pub fn active_imports_count(&self) -> usize {
|
||||
self.import_progress.active_imports()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user