|
1 | 1 | use anyhow::Result; |
2 | 2 | use crossbeam_channel::{Receiver, Sender}; |
3 | 3 | use rusqlite::{Connection, Row, types::ValueRef}; |
| 4 | +use std::collections::HashMap; |
4 | 5 | use std::fs::File; |
5 | 6 | use std::io::{BufWriter, Write}; |
6 | | -use std::collections::HashMap; |
7 | 7 |
|
8 | 8 | #[derive(Debug, Clone, Copy)] |
9 | 9 | pub enum SortDir { |
@@ -101,7 +101,18 @@ pub fn start_db_worker(path: String, req_rx: Receiver<DBRequest>, resp_tx: Sende |
101 | 101 | filter, |
102 | 102 | sort_by, |
103 | 103 | sort_dir, |
104 | | - } => load_table(&conn, &table, page, page_size, offset_override, filter, sort_by, sort_dir), |
| 104 | + } => { |
| 105 | + let params = LoadTableParams { |
| 106 | + table, |
| 107 | + page, |
| 108 | + page_size, |
| 109 | + offset_override, |
| 110 | + filter, |
| 111 | + sort_by, |
| 112 | + sort_dir, |
| 113 | + }; |
| 114 | + load_table(&conn, ¶ms) |
| 115 | + } |
105 | 116 | DBRequest::UpdateCell { |
106 | 117 | table, |
107 | 118 | rowid, |
@@ -139,16 +150,26 @@ fn load_schema(conn: &Connection) -> Result<Vec<String>> { |
139 | 150 | Ok(names) |
140 | 151 | } |
141 | 152 |
|
142 | | -fn load_table( |
143 | | - conn: &Connection, |
144 | | - table: &str, |
| 153 | +struct LoadTableParams { |
| 154 | + table: String, |
145 | 155 | page: usize, |
146 | 156 | page_size: usize, |
147 | 157 | offset_override: Option<usize>, |
148 | 158 | filter: Option<String>, |
149 | 159 | sort_by: Option<String>, |
150 | 160 | sort_dir: Option<SortDir>, |
151 | | -) -> Result<DBResponse> { |
| 161 | +} |
| 162 | + |
| 163 | +fn load_table(conn: &Connection, p: &LoadTableParams) -> Result<DBResponse> { |
| 164 | + // unpack params |
| 165 | + let table = p.table.as_str(); |
| 166 | + let page = p.page; |
| 167 | + let page_size = p.page_size; |
| 168 | + let offset_override = p.offset_override; |
| 169 | + let filter = p.filter.clone(); |
| 170 | + let sort_by = p.sort_by.clone(); |
| 171 | + let sort_dir = p.sort_dir; |
| 172 | + |
152 | 173 | // columns |
153 | 174 | let mut col_stmt = conn.prepare(&format!("PRAGMA table_info({})", ident(table)))?; |
154 | 175 | let mut columns: Vec<String> = vec!["__rowid__".to_string()]; |
@@ -405,7 +426,11 @@ fn update_cell( |
405 | 426 | ) -> Result<DBResponse> { |
406 | 427 | // Fetch previous value for history |
407 | 428 | let prev_value: Option<String> = { |
408 | | - let sql = format!("SELECT {} FROM {} WHERE rowid = ?1", ident(column), ident(table)); |
| 429 | + let sql = format!( |
| 430 | + "SELECT {} FROM {} WHERE rowid = ?1", |
| 431 | + ident(column), |
| 432 | + ident(table) |
| 433 | + ); |
409 | 434 | let mut stmt_prev = conn.prepare(&sql)?; |
410 | 435 | stmt_prev |
411 | 436 | .query_row([rowid], |row| { |
@@ -454,31 +479,31 @@ fn undo_last_change( |
454 | 479 | history: &mut HashMap<String, Vec<Change>>, |
455 | 480 | table: &str, |
456 | 481 | ) -> Result<DBResponse> { |
457 | | - if let Some(stack) = history.get_mut(table) { |
458 | | - if let Some(change) = stack.pop() { |
459 | | - // Apply reverse update: set column back to previous value |
460 | | - let mut stmt = conn.prepare(&format!( |
461 | | - "UPDATE {} SET {} = ?1 WHERE rowid = ?2", |
462 | | - ident(&change.table), |
463 | | - ident(&change.column), |
464 | | - ))?; |
465 | | - let value_param = match change.prev_value { |
466 | | - None => rusqlite::types::Value::Null, |
467 | | - Some(ref s) => parse_value(s), |
468 | | - }; |
469 | | - match stmt.execute((value_param, change.rowid)) { |
470 | | - Ok(_) => { |
471 | | - return Ok(DBResponse::CellUpdated { |
472 | | - ok: true, |
473 | | - message: Some("Undo applied".into()), |
474 | | - }); |
475 | | - } |
476 | | - Err(e) => { |
477 | | - return Ok(DBResponse::CellUpdated { |
478 | | - ok: false, |
479 | | - message: Some(format!("Undo failed: {}", e)), |
480 | | - }); |
481 | | - } |
| 482 | + if let Some(stack) = history.get_mut(table) |
| 483 | + && let Some(change) = stack.pop() |
| 484 | + { |
| 485 | + // Apply reverse update: set column back to previous value |
| 486 | + let mut stmt = conn.prepare(&format!( |
| 487 | + "UPDATE {} SET {} = ?1 WHERE rowid = ?2", |
| 488 | + ident(&change.table), |
| 489 | + ident(&change.column), |
| 490 | + ))?; |
| 491 | + let value_param = match change.prev_value { |
| 492 | + None => rusqlite::types::Value::Null, |
| 493 | + Some(ref s) => parse_value(s), |
| 494 | + }; |
| 495 | + match stmt.execute((value_param, change.rowid)) { |
| 496 | + Ok(_) => { |
| 497 | + return Ok(DBResponse::CellUpdated { |
| 498 | + ok: true, |
| 499 | + message: Some("Undo applied".into()), |
| 500 | + }); |
| 501 | + } |
| 502 | + Err(e) => { |
| 503 | + return Ok(DBResponse::CellUpdated { |
| 504 | + ok: false, |
| 505 | + message: Some(format!("Undo failed: {}", e)), |
| 506 | + }); |
482 | 507 | } |
483 | 508 | } |
484 | 509 | } |
|
0 commit comments