diff --git a/martin-mbtiles/src/bin/main.rs b/martin-mbtiles/src/bin/main.rs index ed0f1b505..91a2fe56e 100644 --- a/martin-mbtiles/src/bin/main.rs +++ b/martin-mbtiles/src/bin/main.rs @@ -13,6 +13,9 @@ use sqlx::{Connection, SqliteConnection}; about = "A utility to work with .mbtiles file content" )] pub struct Args { + /// Display detailed information + #[arg(short, long)] + verbose: bool, #[command(subcommand)] command: Commands, } @@ -46,9 +49,6 @@ enum Commands { src_file: PathBuf, /// MBTiles file to write to dst_file: PathBuf, - /// Display detailed copying information - #[arg(short, long)] - verbose: bool, /// Minimum zoom level to copy #[arg(long)] min_zoom: Option, @@ -72,21 +72,21 @@ async fn main() -> Result<()> { Commands::Copy { src_file, dst_file, - verbose, min_zoom, max_zoom, zoom_levels, } => { - let mut tile_copier_options = - TileCopierOptions::new().verbose(verbose).zooms(zoom_levels); + let mut copy_opts = TileCopierOptions::new() + .verbose(args.verbose) + .zooms(zoom_levels); if let Some(v) = min_zoom { - tile_copier_options = tile_copier_options.min_zoom(v); + copy_opts = copy_opts.min_zoom(v); }; if let Some(v) = max_zoom { - tile_copier_options = tile_copier_options.max_zoom(v); + copy_opts = copy_opts.max_zoom(v); }; - let tile_copier = TileCopier::new(src_file, dst_file, tile_copier_options)?; + let tile_copier = TileCopier::new(src_file, dst_file, copy_opts)?; tile_copier.run().await?; } diff --git a/martin-mbtiles/src/mbtiles.rs b/martin-mbtiles/src/mbtiles.rs index 94510203d..73079ec86 100644 --- a/martin-mbtiles/src/mbtiles.rs +++ b/martin-mbtiles/src/mbtiles.rs @@ -27,7 +27,7 @@ pub struct Metadata { } #[derive(Debug, PartialEq)] -pub enum Type { +pub enum MbtType { TileTables, DeDuplicated, } @@ -276,14 +276,14 @@ impl Mbtiles { Ok(None) } - pub async fn detect_type(&self, conn: &mut T) -> MbtResult + pub async fn detect_type(&self, conn: &mut T) -> MbtResult where for<'e> &'e mut T: SqliteExecutor<'e>, { if is_deduplicated_type(&mut *conn).await? { - Ok(Type::DeDuplicated) + Ok(MbtType::DeDuplicated) } else if is_tile_tables_type(&mut *conn).await? { - Ok(Type::TileTables) + Ok(MbtType::TileTables) } else { Err(MbtError::InvalidDataFormat(self.filepath.clone())) } @@ -384,11 +384,11 @@ mod tests { async fn detect_type() { let (mut conn, mbt) = open("../tests/fixtures/files/world_cities.mbtiles").await; let res = mbt.detect_type(&mut conn).await.unwrap(); - assert_eq!(res, Type::TileTables); + assert_eq!(res, MbtType::TileTables); let (mut conn, mbt) = open("../tests/fixtures/files/geography-class-jpg.mbtiles").await; let res = mbt.detect_type(&mut conn).await.unwrap(); - assert_eq!(res, Type::DeDuplicated); + assert_eq!(res, MbtType::DeDuplicated); let (mut conn, mbt) = open(":memory:").await; let res = mbt.detect_type(&mut conn).await; diff --git a/martin-mbtiles/src/tile_copier.rs b/martin-mbtiles/src/tile_copier.rs index f7b110b17..0f846345c 100644 --- a/martin-mbtiles/src/tile_copier.rs +++ b/martin-mbtiles/src/tile_copier.rs @@ -1,7 +1,7 @@ extern crate core; use crate::errors::MbtResult; -use crate::mbtiles::Type; +use crate::mbtiles::MbtType; use crate::{MbtError, Mbtiles}; use sqlx::sqlite::SqliteConnectOptions; use sqlx::{query, Connection, Row, SqliteConnection}; @@ -56,6 +56,7 @@ impl TileCopierOptions { self } } + impl TileCopier { pub fn new( src_filepath: PathBuf, @@ -111,40 +112,35 @@ impl TileCopier { .await?; match storage_type { - Type::TileTables => self.copy_standard_compliant_tiles(&mut conn).await, - Type::DeDuplicated => self.copy_deduplicated_tiles(&mut conn).await, + MbtType::TileTables => self.copy_tile_tables(&mut conn).await, + MbtType::DeDuplicated => self.copy_deduplicated(&mut conn).await, } } - async fn copy_standard_compliant_tiles(&self, conn: &mut SqliteConnection) -> MbtResult<()> { + async fn copy_tile_tables(&self, conn: &mut SqliteConnection) -> MbtResult<()> { // TODO: Handle options // - bbox // - verbose // - zoom - self.run_query_with_options( - conn, - String::from("INSERT INTO tiles SELECT * FROM sourceDb.tiles"), - ) - .await?; + self.run_query_with_options(conn, "INSERT INTO tiles SELECT * FROM sourceDb.tiles") + .await?; Ok(()) } - async fn copy_deduplicated_tiles(&self, conn: &mut SqliteConnection) -> MbtResult<()> { + async fn copy_deduplicated(&self, conn: &mut SqliteConnection) -> MbtResult<()> { query("INSERT INTO map SELECT * FROM sourceDb.map") .execute(&mut *conn) .await?; self.run_query_with_options( conn, - String::from( - "INSERT INTO images + "INSERT INTO images SELECT images.tile_data, images.tile_id FROM sourceDb.images JOIN sourceDb.map ON images.tile_id = map.tile_id", - ), ) .await?; @@ -154,37 +150,31 @@ impl TileCopier { async fn run_query_with_options( &self, conn: &mut SqliteConnection, - mut sql: String, + sql: &str, ) -> MbtResult<()> { let mut params: Vec = vec![]; - if !&self.options.zooms.is_empty() { - sql.push_str( - format!( - " WHERE zoom_level IN ({})", - vec!["?"; self.options.zooms.len()].join(",") - ) - .as_str(), - ); - for zoom_level in &self.options.zooms { - params.push(zoom_level.to_string()); - } + let sql = if !&self.options.zooms.is_empty() { + params.extend(self.options.zooms.iter().map(|z| z.to_string())); + format!( + "{sql} WHERE zoom_level IN ({})", + vec!["?"; self.options.zooms.len()].join(",") + ) } else if let Some(min_zoom) = &self.options.min_zoom { if let Some(max_zoom) = &self.options.max_zoom { - sql.push_str(" WHERE zoom_level BETWEEN ? AND ?"); - params.push(min_zoom.to_string()); params.push(max_zoom.to_string()); + format!("{sql} WHERE zoom_level BETWEEN ? AND ?") } else { - sql.push_str(" WHERE zoom_level >= ? "); - params.push(min_zoom.to_string()); + format!("{sql} WHERE zoom_level >= ? ") } } else if let Some(max_zoom) = &self.options.max_zoom { - sql.push_str(" WHERE zoom_level <= ? "); - params.push(max_zoom.to_string()); - } + format!("{sql} WHERE zoom_level <= ? ") + } else { + sql.to_string() + }; let mut query = query(sql.as_str()); diff --git a/tests/expected/mbtiles/help.txt b/tests/expected/mbtiles/help.txt index 8a81adae4..937d9f4e2 100644 --- a/tests/expected/mbtiles/help.txt +++ b/tests/expected/mbtiles/help.txt @@ -1,11 +1,13 @@ A utility to work with .mbtiles file content -Usage: mbtiles +Usage: mbtiles [OPTIONS] Commands: meta-get Gets a single value from the MBTiles metadata table + copy Copy tiles from one mbtiles file to another help Print this message or the help of the given subcommand(s) Options: + -v, --verbose Display detailed information -h, --help Print help -V, --version Print version