mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
Add debugging utilities and improved package listing
- Add support for debugging database tables with `--stats`, `--dump-all`, and `--dump-table` options. - Introduce CLI command `DebugDb` for inspecting catalog, obsoleted, and installed tables. - Enhance `List` command to include an `--all` flag for listing all available packages. - Update logging for database operations and package queries. - Add methods to dump and analyze table contents in `InstalledPackages` and `ImageCatalog`.
This commit is contained in:
parent
0ec1c1928a
commit
92cce0f767
3 changed files with 483 additions and 3 deletions
|
|
@ -90,6 +90,206 @@ impl ImageCatalog {
|
|||
}
|
||||
}
|
||||
|
||||
/// Dump the contents of a specific table to stdout for debugging
|
||||
pub fn dump_table(&self, table_name: &str) -> Result<()> {
|
||||
// Open the database
|
||||
let db = Database::open(&self.db_path)
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to open database: {}", e)))?;
|
||||
|
||||
// Begin a read transaction
|
||||
let tx = db.begin_read()
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to begin transaction: {}", e)))?;
|
||||
|
||||
// Determine which table to dump
|
||||
match table_name {
|
||||
"catalog" => self.dump_catalog_table(&tx)?,
|
||||
"obsoleted" => self.dump_obsoleted_table(&tx)?,
|
||||
"installed" => self.dump_installed_table(&tx)?,
|
||||
_ => return Err(CatalogError::Database(format!("Unknown table: {}", table_name))),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Dump the contents of all tables to stdout for debugging
|
||||
pub fn dump_all_tables(&self) -> Result<()> {
|
||||
// Open the database
|
||||
let db = Database::open(&self.db_path)
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to open database: {}", e)))?;
|
||||
|
||||
// Begin a read transaction
|
||||
let tx = db.begin_read()
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to begin transaction: {}", e)))?;
|
||||
|
||||
println!("=== CATALOG TABLE ===");
|
||||
let _ = self.dump_catalog_table(&tx);
|
||||
|
||||
println!("\n=== OBSOLETED TABLE ===");
|
||||
let _ = self.dump_obsoleted_table(&tx);
|
||||
|
||||
println!("\n=== INSTALLED TABLE ===");
|
||||
let _ = self.dump_installed_table(&tx);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Dump the contents of the catalog table
|
||||
fn dump_catalog_table(&self, tx: &redb::ReadTransaction) -> Result<()> {
|
||||
match tx.open_table(CATALOG_TABLE) {
|
||||
Ok(table) => {
|
||||
let mut count = 0;
|
||||
for entry_result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate catalog table: {}", e)))? {
|
||||
let (key, value) = entry_result.map_err(|e| CatalogError::Database(format!("Failed to get entry from catalog table: {}", e)))?;
|
||||
let key_str = key.value();
|
||||
|
||||
// Try to deserialize the manifest
|
||||
match serde_json::from_slice::<Manifest>(value.value()) {
|
||||
Ok(manifest) => {
|
||||
// Extract the publisher from the FMRI attribute
|
||||
let publisher = manifest.attributes.iter()
|
||||
.find(|attr| attr.key == "pkg.fmri")
|
||||
.and_then(|attr| attr.values.get(0).cloned())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
println!("Key: {}", key_str);
|
||||
println!(" FMRI: {}", publisher);
|
||||
println!(" Attributes: {}", manifest.attributes.len());
|
||||
println!(" Files: {}", manifest.files.len());
|
||||
println!(" Directories: {}", manifest.directories.len());
|
||||
println!(" Dependencies: {}", manifest.dependencies.len());
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Key: {}", key_str);
|
||||
println!(" Error deserializing manifest: {}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
println!("Total entries in catalog table: {}", count);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error opening catalog table: {}", e);
|
||||
Err(CatalogError::Database(format!("Failed to open catalog table: {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dump the contents of the obsoleted table
|
||||
fn dump_obsoleted_table(&self, tx: &redb::ReadTransaction) -> Result<()> {
|
||||
match tx.open_table(OBSOLETED_TABLE) {
|
||||
Ok(table) => {
|
||||
let mut count = 0;
|
||||
for entry_result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate obsoleted table: {}", e)))? {
|
||||
let (key, _) = entry_result.map_err(|e| CatalogError::Database(format!("Failed to get entry from obsoleted table: {}", e)))?;
|
||||
let key_str = key.value();
|
||||
|
||||
println!("Key: {}", key_str);
|
||||
count += 1;
|
||||
}
|
||||
println!("Total entries in obsoleted table: {}", count);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error opening obsoleted table: {}", e);
|
||||
Err(CatalogError::Database(format!("Failed to open obsoleted table: {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dump the contents of the installed table
|
||||
fn dump_installed_table(&self, tx: &redb::ReadTransaction) -> Result<()> {
|
||||
match tx.open_table(INSTALLED_TABLE) {
|
||||
Ok(table) => {
|
||||
let mut count = 0;
|
||||
for entry_result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate installed table: {}", e)))? {
|
||||
let (key, value) = entry_result.map_err(|e| CatalogError::Database(format!("Failed to get entry from installed table: {}", e)))?;
|
||||
let key_str = key.value();
|
||||
|
||||
// Try to deserialize the manifest
|
||||
match serde_json::from_slice::<Manifest>(value.value()) {
|
||||
Ok(manifest) => {
|
||||
// Extract the publisher from the FMRI attribute
|
||||
let publisher = manifest.attributes.iter()
|
||||
.find(|attr| attr.key == "pkg.fmri")
|
||||
.and_then(|attr| attr.values.get(0).cloned())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
println!("Key: {}", key_str);
|
||||
println!(" FMRI: {}", publisher);
|
||||
println!(" Attributes: {}", manifest.attributes.len());
|
||||
println!(" Files: {}", manifest.files.len());
|
||||
println!(" Directories: {}", manifest.directories.len());
|
||||
println!(" Dependencies: {}", manifest.dependencies.len());
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Key: {}", key_str);
|
||||
println!(" Error deserializing manifest: {}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
println!("Total entries in installed table: {}", count);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error opening installed table: {}", e);
|
||||
Err(CatalogError::Database(format!("Failed to open installed table: {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get database statistics
|
||||
pub fn get_db_stats(&self) -> Result<()> {
|
||||
// Open the database
|
||||
let db = Database::open(&self.db_path)
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to open database: {}", e)))?;
|
||||
|
||||
// Begin a read transaction
|
||||
let tx = db.begin_read()
|
||||
.map_err(|e| CatalogError::Database(format!("Failed to begin transaction: {}", e)))?;
|
||||
|
||||
// Get table statistics
|
||||
let mut catalog_count = 0;
|
||||
let mut obsoleted_count = 0;
|
||||
let mut installed_count = 0;
|
||||
|
||||
// Count catalog entries
|
||||
if let Ok(table) = tx.open_table(CATALOG_TABLE) {
|
||||
for result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate catalog table: {}", e)))? {
|
||||
let _ = result.map_err(|e| CatalogError::Database(format!("Failed to get entry from catalog table: {}", e)))?;
|
||||
catalog_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Count obsoleted entries
|
||||
if let Ok(table) = tx.open_table(OBSOLETED_TABLE) {
|
||||
for result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate obsoleted table: {}", e)))? {
|
||||
let _ = result.map_err(|e| CatalogError::Database(format!("Failed to get entry from obsoleted table: {}", e)))?;
|
||||
obsoleted_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Count installed entries
|
||||
if let Ok(table) = tx.open_table(INSTALLED_TABLE) {
|
||||
for result in table.iter().map_err(|e| CatalogError::Database(format!("Failed to iterate installed table: {}", e)))? {
|
||||
let _ = result.map_err(|e| CatalogError::Database(format!("Failed to get entry from installed table: {}", e)))?;
|
||||
installed_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Print statistics
|
||||
println!("Database path: {}", self.db_path.display());
|
||||
println!("Catalog directory: {}", self.catalog_dir.display());
|
||||
println!("Table statistics:");
|
||||
println!(" Catalog table: {} entries", catalog_count);
|
||||
println!(" Obsoleted table: {} entries", obsoleted_count);
|
||||
println!(" Installed table: {} entries", installed_count);
|
||||
println!("Total entries: {}", catalog_count + obsoleted_count + installed_count);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialize the catalog database
|
||||
pub fn init_db(&self) -> Result<()> {
|
||||
// Create a parent directory if it doesn't exist
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use std::fs;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
use tracing::{info};
|
||||
use tracing::{info, warn};
|
||||
|
||||
/// Table definition for the installed packages database
|
||||
/// Key: full FMRI including publisher (pkg://publisher/stem@version)
|
||||
|
|
@ -76,6 +76,87 @@ impl InstalledPackages {
|
|||
}
|
||||
}
|
||||
|
||||
/// Dump the contents of the installed table to stdout for debugging
|
||||
pub fn dump_installed_table(&self) -> Result<()> {
|
||||
// Open the database
|
||||
let db = Database::open(&self.db_path)
|
||||
.map_err(|e| InstalledError::Database(format!("Failed to open database: {}", e)))?;
|
||||
|
||||
// Begin a read transaction
|
||||
let tx = db.begin_read()
|
||||
.map_err(|e| InstalledError::Database(format!("Failed to begin transaction: {}", e)))?;
|
||||
|
||||
// Open the installed table
|
||||
match tx.open_table(INSTALLED_TABLE) {
|
||||
Ok(table) => {
|
||||
let mut count = 0;
|
||||
for entry_result in table.iter().map_err(|e| InstalledError::Database(format!("Failed to iterate installed table: {}", e)))? {
|
||||
let (key, value) = entry_result.map_err(|e| InstalledError::Database(format!("Failed to get entry from installed table: {}", e)))?;
|
||||
let key_str = key.value();
|
||||
|
||||
// Try to deserialize the manifest
|
||||
match serde_json::from_slice::<Manifest>(value.value()) {
|
||||
Ok(manifest) => {
|
||||
// Extract the publisher from the FMRI attribute
|
||||
let publisher = manifest.attributes.iter()
|
||||
.find(|attr| attr.key == "pkg.fmri")
|
||||
.and_then(|attr| attr.values.get(0).cloned())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
println!("Key: {}", key_str);
|
||||
println!(" FMRI: {}", publisher);
|
||||
println!(" Attributes: {}", manifest.attributes.len());
|
||||
println!(" Files: {}", manifest.files.len());
|
||||
println!(" Directories: {}", manifest.directories.len());
|
||||
println!(" Dependencies: {}", manifest.dependencies.len());
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Key: {}", key_str);
|
||||
println!(" Error deserializing manifest: {}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
println!("Total entries in installed table: {}", count);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error opening installed table: {}", e);
|
||||
Err(InstalledError::Database(format!("Failed to open installed table: {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get database statistics
|
||||
pub fn get_db_stats(&self) -> Result<()> {
|
||||
// Open the database
|
||||
let db = Database::open(&self.db_path)
|
||||
.map_err(|e| InstalledError::Database(format!("Failed to open database: {}", e)))?;
|
||||
|
||||
// Begin a read transaction
|
||||
let tx = db.begin_read()
|
||||
.map_err(|e| InstalledError::Database(format!("Failed to begin transaction: {}", e)))?;
|
||||
|
||||
// Get table statistics
|
||||
let mut installed_count = 0;
|
||||
|
||||
// Count installed entries
|
||||
if let Ok(table) = tx.open_table(INSTALLED_TABLE) {
|
||||
for result in table.iter().map_err(|e| InstalledError::Database(format!("Failed to iterate installed table: {}", e)))? {
|
||||
let _ = result.map_err(|e| InstalledError::Database(format!("Failed to get entry from installed table: {}", e)))?;
|
||||
installed_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Print statistics
|
||||
println!("Database path: {}", self.db_path.display());
|
||||
println!("Table statistics:");
|
||||
println!(" Installed table: {} entries", installed_count);
|
||||
println!("Total entries: {}", installed_count);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialize the installed packages database
|
||||
pub fn init_db(&self) -> Result<()> {
|
||||
// Create a parent directory if it doesn't exist
|
||||
|
|
|
|||
203
pkg6/src/main.rs
203
pkg6/src/main.rs
|
|
@ -228,6 +228,7 @@ enum Commands {
|
|||
/// List installed packages
|
||||
///
|
||||
/// The list command displays information about installed packages.
|
||||
/// By default, it lists only installed packages. Use the -a flag to list all available packages.
|
||||
List {
|
||||
/// Verbose output
|
||||
#[clap(short)]
|
||||
|
|
@ -237,6 +238,10 @@ enum Commands {
|
|||
#[clap(short)]
|
||||
quiet: bool,
|
||||
|
||||
/// List all available packages, not just installed ones
|
||||
#[clap(short)]
|
||||
all: bool,
|
||||
|
||||
/// Output format (default: table)
|
||||
#[clap(short = 'o')]
|
||||
output_format: Option<String>,
|
||||
|
|
@ -422,6 +427,35 @@ enum Commands {
|
|||
#[clap(short = 't', long = "type", default_value = "full")]
|
||||
image_type: String,
|
||||
},
|
||||
|
||||
/// Debug database commands (hidden)
|
||||
///
|
||||
/// These commands are for debugging purposes only and are not part of the public API.
|
||||
/// They are used to inspect the contents of the redb databases for debugging purposes.
|
||||
///
|
||||
/// Usage examples:
|
||||
/// - Show database statistics: pkg6 debug-db --stats
|
||||
/// - Dump all tables: pkg6 debug-db --dump-all
|
||||
/// - Dump a specific table: pkg6 debug-db --dump-table catalog
|
||||
///
|
||||
/// Available tables:
|
||||
/// - catalog: Contains non-obsolete packages (in catalog.redb)
|
||||
/// - obsoleted: Contains obsolete packages (in catalog.redb)
|
||||
/// - installed: Contains installed packages (in installed.redb)
|
||||
#[clap(hide = true)]
|
||||
DebugDb {
|
||||
/// Show database statistics
|
||||
#[clap(long)]
|
||||
stats: bool,
|
||||
|
||||
/// Dump all tables
|
||||
#[clap(long)]
|
||||
dump_all: bool,
|
||||
|
||||
/// Dump a specific table (catalog, obsoleted, installed)
|
||||
#[clap(long)]
|
||||
dump_table: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Determines the image path to use based on the provided argument and default rules
|
||||
|
|
@ -478,6 +512,7 @@ fn main() -> Result<()> {
|
|||
// Print the command that was parsed
|
||||
match &cli.command {
|
||||
Commands::Publisher { .. } => eprintln!("MAIN: Publisher command detected"),
|
||||
Commands::DebugDb { .. } => eprintln!("MAIN: Debug database command detected"),
|
||||
_ => eprintln!("MAIN: Other command detected: {:?}", cli.command),
|
||||
};
|
||||
|
||||
|
|
@ -580,13 +615,84 @@ fn main() -> Result<()> {
|
|||
info!("Update completed successfully");
|
||||
Ok(())
|
||||
},
|
||||
Commands::List { verbose, quiet, output_format, pkg_fmri_patterns } => {
|
||||
Commands::List { verbose, quiet, all, output_format, pkg_fmri_patterns } => {
|
||||
info!("Listing packages: {:?}", pkg_fmri_patterns);
|
||||
debug!("Verbose: {}", verbose);
|
||||
debug!("Quiet: {}", quiet);
|
||||
debug!("All packages: {}", all);
|
||||
debug!("Output format: {:?}", output_format);
|
||||
|
||||
// Stub implementation
|
||||
// Determine the image path using the -R argument or default rules
|
||||
let image_path = determine_image_path(cli.image_path.clone());
|
||||
info!("Using image at: {}", image_path.display());
|
||||
|
||||
// Try to load the image from the determined path
|
||||
let image = match libips::image::Image::load(&image_path) {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
error!("Failed to load image from {}: {}", image_path.display(), e);
|
||||
error!("Make sure the path points to a valid image or use pkg6 image-create first");
|
||||
return Err(e.into());
|
||||
}
|
||||
};
|
||||
|
||||
// Convert pkg_fmri_patterns to a single pattern if provided
|
||||
let pattern = if pkg_fmri_patterns.is_empty() {
|
||||
None
|
||||
} else {
|
||||
// For simplicity, we'll just use the first pattern
|
||||
// In a more complete implementation, we would handle multiple patterns
|
||||
Some(pkg_fmri_patterns[0].as_str())
|
||||
};
|
||||
|
||||
if *all {
|
||||
// List all available packages
|
||||
info!("Listing all available packages");
|
||||
|
||||
match image.query_catalog(pattern) {
|
||||
Ok(packages) => {
|
||||
println!("PUBLISHER NAME VERSION STATE");
|
||||
println!("------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||
for pkg in packages {
|
||||
let state = if image.is_package_installed(&pkg.fmri).unwrap_or(false) {
|
||||
"installed"
|
||||
} else {
|
||||
"known"
|
||||
};
|
||||
println!("{:<40} {:<40} {:<30} {}",
|
||||
pkg.fmri.publisher.as_deref().unwrap_or("unknown"),
|
||||
pkg.fmri.name,
|
||||
pkg.fmri.version(),
|
||||
state);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to query catalog: {}", e);
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// List only installed packages
|
||||
info!("Listing installed packages");
|
||||
match image.query_installed_packages(pattern) {
|
||||
Ok(packages) => {
|
||||
println!("PUBLISHER NAME VERSION STATE");
|
||||
println!("------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||
for pkg in packages {
|
||||
println!("{:<40} {:<40} {:<30} {}",
|
||||
pkg.fmri.publisher.as_deref().unwrap_or("unknown"),
|
||||
pkg.fmri.name,
|
||||
pkg.fmri.version(),
|
||||
"installed");
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to query installed packages: {}", e);
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("List completed successfully");
|
||||
Ok(())
|
||||
},
|
||||
|
|
@ -906,5 +1012,98 @@ fn main() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
},
|
||||
Commands::DebugDb { stats, dump_all, dump_table } => {
|
||||
info!("Debug database command");
|
||||
debug!("Stats: {}", stats);
|
||||
debug!("Dump all: {}", dump_all);
|
||||
debug!("Dump table: {:?}", dump_table);
|
||||
|
||||
// Determine the image path using the -R argument or default rules
|
||||
let image_path = determine_image_path(cli.image_path.clone());
|
||||
info!("Using image at: {}", image_path.display());
|
||||
|
||||
// Try to load the image from the determined path
|
||||
let image = match libips::image::Image::load(&image_path) {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
error!("Failed to load image from {}: {}", image_path.display(), e);
|
||||
error!("Make sure the path points to a valid image or use pkg6 image-create first");
|
||||
return Err(e.into());
|
||||
}
|
||||
};
|
||||
|
||||
// Create a catalog object for the catalog.redb database
|
||||
let catalog = libips::image::catalog::ImageCatalog::new(
|
||||
image.catalog_dir(),
|
||||
image.catalog_db_path()
|
||||
);
|
||||
|
||||
// Create an installed packages object for the installed.redb database
|
||||
let installed = libips::image::installed::InstalledPackages::new(
|
||||
image.installed_db_path()
|
||||
);
|
||||
|
||||
// Execute the requested debug command
|
||||
if *stats {
|
||||
info!("Showing database statistics");
|
||||
println!("=== CATALOG DATABASE ===");
|
||||
if let Err(e) = catalog.get_db_stats() {
|
||||
error!("Failed to get catalog database statistics: {}", e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to get catalog database statistics: {}", e)));
|
||||
}
|
||||
|
||||
println!("\n=== INSTALLED DATABASE ===");
|
||||
if let Err(e) = installed.get_db_stats() {
|
||||
error!("Failed to get installed database statistics: {}", e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to get installed database statistics: {}", e)));
|
||||
}
|
||||
}
|
||||
|
||||
if *dump_all {
|
||||
info!("Dumping all tables");
|
||||
println!("=== CATALOG DATABASE ===");
|
||||
if let Err(e) = catalog.dump_all_tables() {
|
||||
error!("Failed to dump catalog database tables: {}", e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to dump catalog database tables: {}", e)));
|
||||
}
|
||||
|
||||
println!("\n=== INSTALLED DATABASE ===");
|
||||
if let Err(e) = installed.dump_installed_table() {
|
||||
error!("Failed to dump installed database table: {}", e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to dump installed database table: {}", e)));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(table_name) = dump_table {
|
||||
info!("Dumping table: {}", table_name);
|
||||
|
||||
// Determine which database to use based on the table name
|
||||
match table_name.as_str() {
|
||||
"installed" => {
|
||||
// Use the installed packages database
|
||||
println!("=== INSTALLED DATABASE ===");
|
||||
if let Err(e) = installed.dump_installed_table() {
|
||||
error!("Failed to dump installed table: {}", e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to dump installed table: {}", e)));
|
||||
}
|
||||
},
|
||||
"catalog" | "obsoleted" => {
|
||||
// Use the catalog database
|
||||
println!("=== CATALOG DATABASE ===");
|
||||
if let Err(e) = catalog.dump_table(table_name) {
|
||||
error!("Failed to dump table {}: {}", table_name, e);
|
||||
return Err(Pkg6Error::Other(format!("Failed to dump table {}: {}", table_name, e)));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
error!("Unknown table: {}", table_name);
|
||||
return Err(Pkg6Error::Other(format!("Unknown table: {}. Available tables: catalog, obsoleted, installed", table_name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("Debug database command completed successfully");
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue