diff --git a/cli/app.rs b/cli/app.rs index 5e2ae801c..8907ae1b2 100644 --- a/cli/app.rs +++ b/cli/app.rs @@ -949,44 +949,25 @@ impl Limbo { // Get column information using PRAGMA table_info let pragma_sql = format!("PRAGMA table_info({view_name})"); - match self.conn.query(&pragma_sql) { - Ok(Some(ref mut rows)) => { - let mut columns = Vec::new(); - loop { - match rows.step()? { - StepResult::Row => { - let row = rows.row().unwrap(); - // Column name is in the second column (index 1) of PRAGMA table_info - if let Ok(Value::Text(col_name)) = row.get::<&Value>(1) { - columns.push(col_name.as_str().to_string()); - } - } - StepResult::IO => { - rows.run_once()?; - } - StepResult::Done => break, - StepResult::Interrupt => break, - StepResult::Busy => break, - } - } - - if columns.is_empty() { - anyhow::bail!("PRAGMA table_info returned no columns for view '{}'. The view may be corrupted or the database schema is invalid.", view_name); - } - - Ok(columns.join(",")) - } - Ok(None) => { - anyhow::bail!("PRAGMA table_info('{}') returned no results. The view may not exist or the database schema is invalid.", view_name); - } - Err(e) => { - anyhow::bail!( - "Failed to execute PRAGMA table_info for view '{}': {}", - view_name, - e - ); + let mut columns = Vec::new(); + let handler = |row: &turso_core::Row, _writer: &mut dyn Write| -> anyhow::Result<()> { + // Column name is in the second column (index 1) of PRAGMA table_info + if let Ok(Value::Text(col_name)) = row.get::<&Value>(1) { + columns.push(col_name.as_str().to_string()); } + Ok(()) + }; + if let Err(err) = self.handle_row(&pragma_sql, handler) { + return Err(anyhow::anyhow!( + "Error retrieving columns for view '{}': {}", + view_name, + err + )); } + if columns.is_empty() { + anyhow::bail!("PRAGMA table_info returned no columns for view '{}'. The view may be corrupted or the database schema is invalid.", view_name); + } + Ok(columns.join(",")) } fn query_one_table_schema( @@ -1123,43 +1104,24 @@ impl Limbo { None => String::from("SELECT name FROM sqlite_schema WHERE type='index' ORDER BY 1"), }; - match self.conn.query(&sql) { - Ok(Some(ref mut rows)) => { - let mut indexes = String::new(); - loop { - match rows.step()? { - StepResult::Row => { - let row = rows.row().unwrap(); - if let Ok(Value::Text(idx)) = row.get::<&Value>(0) { - indexes.push_str(idx.as_str()); - indexes.push(' '); - } - } - StepResult::IO => { - rows.run_once()?; - } - StepResult::Interrupt => break, - StepResult::Done => break, - StepResult::Busy => { - let _ = self.writeln("database is busy"); - break; - } - } - } - if !indexes.is_empty() { - let _ = self.writeln(indexes.trim_end()); - } + let mut indexes = String::new(); + let handler = |row: &turso_core::Row, _writer: &mut dyn Write| -> anyhow::Result<()> { + if let Ok(Value::Text(idx)) = row.get::<&Value>(0) { + indexes.push_str(idx.as_str()); + indexes.push(' '); } - Err(err) => { - if err.to_string().contains("no such table: sqlite_schema") { - return Err(anyhow::anyhow!("Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized.")); - } else { - return Err(anyhow::anyhow!("Error querying schema: {}", err)); - } + Ok(()) + }; + if let Err(err) = self.handle_row(&sql, handler) { + if err.to_string().contains("no such table: sqlite_schema") { + return Err(anyhow::anyhow!("Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized.")); + } else { + return Err(anyhow::anyhow!("Error querying schema: {}", err)); } - Ok(None) => {} } - + if !indexes.is_empty() { + let _ = self.writeln(indexes.trim_end().as_bytes()); + } Ok(()) } @@ -1173,52 +1135,62 @@ impl Limbo { ), }; - match self.conn.query(&sql) { - Ok(Some(ref mut rows)) => { - let mut tables = String::new(); - loop { - match rows.step()? { - StepResult::Row => { - let row = rows.row().unwrap(); - if let Ok(Value::Text(table)) = row.get::<&Value>(0) { - tables.push_str(table.as_str()); - tables.push(' '); - } - } - StepResult::IO => { - rows.run_once()?; - } - StepResult::Interrupt => break, - StepResult::Done => break, - StepResult::Busy => { - let _ = self.writeln("database is busy"); - break; - } + let mut tables = String::new(); + let handler = |row: &turso_core::Row, _writer: &mut dyn Write| -> anyhow::Result<()> { + if let Ok(Value::Text(table)) = row.get::<&Value>(0) { + tables.push_str(table.as_str()); + tables.push(' '); + } + Ok(()) + }; + if let Err(e) = self.handle_row(&sql, handler) { + if e.to_string().contains("no such table: sqlite_schema") { + return Err(anyhow::anyhow!("Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized.")); + } else { + return Err(anyhow::anyhow!("Error querying schema: {}", e)); + } + } + if !tables.is_empty() { + let _ = self.writeln(tables.trim_end().as_bytes()); + } else if let Some(pattern) = pattern { + let _ = self.write_fmt(format_args!( + "Error: Tables with pattern '{pattern}' not found." + )); + } else { + let _ = self.writeln(b"No tables found in the database."); + } + Ok(()) + } + + fn handle_row(&mut self, sql: &str, mut handler: F) -> anyhow::Result<()> + where + F: FnMut(&turso_core::Row, &mut dyn Write) -> anyhow::Result<()>, + { + match self.conn.query(sql) { + Ok(Some(ref mut rows)) => loop { + match rows.step()? { + StepResult::Row => { + let row = rows.row().unwrap(); + handler(row, self.writer.as_mut().unwrap())?; + } + StepResult::IO => { + rows.run_once()?; + } + StepResult::Interrupt => break, + StepResult::Done => break, + StepResult::Busy => { + let _ = self.writeln("database is busy"); + break; } } - - if !tables.is_empty() { - let _ = self.writeln(tables.trim_end()); - } else if let Some(pattern) = pattern { - let _ = self.write_fmt(format_args!( - "Error: Tables with pattern '{pattern}' not found." - )); - } else { - let _ = self.writeln("No tables found in the database."); - } - } + }, Ok(None) => { let _ = self.writeln("No results returned from the query."); } Err(err) => { - if err.to_string().contains("no such table: sqlite_schema") { - return Err(anyhow::anyhow!("Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized.")); - } else { - return Err(anyhow::anyhow!("Error querying schema: {}", err)); - } + return Err(anyhow::anyhow!("Error querying database: {}", err)); } } - Ok(()) }