Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions mbtiles/src/bin/mbtiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,27 @@ pub struct Args {
#[allow(clippy::doc_markdown)]
#[derive(Subcommand, PartialEq, Debug)]
enum Commands {
/// Show MBTiles file summary statistics
/// Show `MBTiles` file summary statistics
#[command(name = "summary", alias = "info")]
Summary { file: PathBuf },
/// Prints all values in the metadata table in a free-style, unstable YAML format
#[command(name = "meta-all")]
MetaAll {
/// MBTiles file to read from
/// `MBTiles` file to read from
file: PathBuf,
},
/// Gets a single value from the MBTiles metadata table.
/// Gets a single value from the `MBTiles` metadata table.
#[command(name = "meta-get", alias = "get-meta")]
MetaGetValue {
/// MBTiles file to read a value from
/// `MBTiles` file to read a value from
file: PathBuf,
/// Value to read
key: String,
},
/// Sets a single value in the MBTiles metadata table or deletes it if no value.
/// Sets a single value in the `MBTiles` metadata table or deletes it if no value.
#[command(name = "meta-set", alias = "set-meta")]
MetaSetValue {
/// MBTiles file to modify
/// `MBTiles` file to modify
file: PathBuf,
/// Key to set
key: String,
Expand All @@ -62,7 +62,7 @@ enum Commands {
/// Apply diff file generated from 'copy' command
#[command(name = "apply-patch", alias = "apply-diff")]
ApplyPatch {
/// MBTiles file to apply diff to
/// `MBTiles` file to apply diff to
base_file: PathBuf,
/// Diff file
patch_file: PathBuf,
Expand All @@ -73,7 +73,7 @@ enum Commands {
/// Update metadata to match the content of the file
#[command(name = "meta-update", alias = "update-meta")]
UpdateMetadata {
/// MBTiles file to validate
/// `MBTiles` file to validate
file: PathBuf,
/// Update the min and max zoom levels in the metadata table to match the tiles table.
#[arg(long, value_enum, default_value_t=UpdateZoomType::default())]
Expand All @@ -82,7 +82,7 @@ enum Commands {
/// Validate tile data if hash of tile data exists in file
#[command(name = "validate", alias = "check", alias = "verify")]
Validate {
/// MBTiles file to validate
/// `MBTiles` file to validate
file: PathBuf,
/// Value to specify the extent of the SQLite integrity check performed
#[arg(long, value_enum, default_value_t=IntegrityCheckType::default())]
Expand All @@ -99,9 +99,9 @@ enum Commands {
#[allow(clippy::doc_markdown)]
#[derive(Clone, Default, PartialEq, Debug, clap::Args)]
pub struct CopyArgs {
/// MBTiles file to read from
/// `MBTiles` file to read from
src_file: PathBuf,
/// MBTiles file to write to
/// `MBTiles` file to write to
dst_file: PathBuf,
#[command(flatten)]
pub options: SharedCopyOpts,
Expand All @@ -123,9 +123,9 @@ pub struct CopyArgs {
#[allow(clippy::doc_markdown)]
#[derive(Clone, Default, PartialEq, Debug, clap::Args)]
pub struct DiffArgs {
/// First MBTiles file to compare
/// First `MBTiles` file to compare
file1: PathBuf,
/// Second MBTiles file to compare
/// Second `MBTiles` file to compare
file2: PathBuf,
/// Output file to write the resulting difference to
diff: PathBuf,
Expand Down
3 changes: 3 additions & 0 deletions mbtiles/src/copier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ impl MbtileCopierInt {
Ok(conn)
}

/// Validate the integrity of the mbtiles file if requested
///
/// See [`Mbtiles::validate`] for the validations performed.
async fn validate(&self, mbt: &Mbtiles, conn: &mut SqliteConnection) -> MbtResult<()> {
if self.options.validate {
mbt.validate(conn, Quick, Verify).await?;
Expand Down
1 change: 1 addition & 0 deletions mbtiles/src/mbtiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl Mbtiles {
Ok(())
}

/// Get a tile from the database
pub async fn get_tile<T>(
&self,
conn: &mut T,
Expand Down
4 changes: 4 additions & 0 deletions mbtiles/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ impl MbtilesPool {
Ok(Self { mbtiles, pool })
}

/// Get the metadata of the `MBTiles` file.
///
/// See [`Metadata`] for more information.
pub async fn get_metadata(&self) -> MbtResult<Metadata> {
let mut conn = self.pool.acquire().await?;
self.mbtiles.get_metadata(&mut *conn).await
}

/// Get a tile from the pool
pub async fn get_tile(&self, z: u8, x: u32, y: u32) -> MbtResult<Option<Vec<u8>>> {
let mut conn = self.pool.acquire().await?;
self.mbtiles.get_tile(&mut *conn, z, x, y).await
Expand Down
34 changes: 34 additions & 0 deletions mbtiles/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,31 @@ pub const AGG_TILES_HASH_BEFORE_APPLY: &str = "agg_tiles_hash_before_apply";
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, EnumDisplay, Serialize)]
#[enum_display(case = "Kebab")]
pub enum MbtType {
/// Flat `MBTiles` file without any hash values
///
/// The closest to the original `MBTiles` specification.
/// It stores all tiles in a single table.
/// This schema is the most efficient when the tileset contains no duplicate tiles.
///
/// See <https://maplibre.org/martin/mbtiles-schema.html#flat> for the concrete schema.
Flat,
/// [`MbtType::Flat`] `MBTiles` file with hash values
///
/// Similar to the [`MbtType::Flat`] schema, but also includes a `tile_hash` column that contains a hash value of the `tile_data` column.
/// Use this schema when the tileset has no duplicate tiles, but you still want to be able to validate the content of each tile individually.
///
/// See <https://maplibre.org/martin/mbtiles-schema.html#flat-with-hash> for the concrete schema.
FlatWithHash,
/// Normalized `MBTiles` file
///
/// The most efficient when the tileset contains duplicate tiles.
/// It stores all tile blobs in the `images` table, and stores the tile Z,X,Y coordinates in a `map` table.
/// The `map` table contains a `tile_id` column that is a foreign key to the `images` table.
/// The `tile_id` column is a hash of the `tile_data` column, making it possible to both validate each individual tile like in the [`MbtType::FlatWithHash`] schema, and also to optimize storage by storing each unique tile only once.
///
/// The `hash_view` argument specifies whether to create/assume a `tiles_with_hash` view exists.
///
/// See <https://maplibre.org/martin/mbtiles-schema.html#normalized> for the concrete schema.
Normalized { hash_view: bool },
}

Expand Down Expand Up @@ -75,6 +98,7 @@ pub enum AggHashType {
}

impl Mbtiles {
/// Open the mbtiles file and validate its integrity.
pub async fn open_and_validate(
&self,
check_type: IntegrityCheckType,
Expand All @@ -88,6 +112,12 @@ impl Mbtiles {
self.validate(&mut conn, check_type, agg_hash).await
}

/// Validate the integrity of the mbtiles file by:
/// - sqlite internal integrity check
/// - tiles' table has the expected column, row, zoom, and data values
/// - each tile has the correct hash stored
///
/// Depending on the `agg_hash` parameter, the function will either verify or update the aggregate tiles hash value.
pub async fn validate<T>(
&self,
conn: &mut T,
Expand Down Expand Up @@ -197,6 +227,7 @@ impl Mbtiles {
}
}

/// Detects the format of a tile and returns its information if none of the values are `None`
fn parse_tile(
&self,
z: Option<i64>,
Expand Down Expand Up @@ -225,6 +256,9 @@ impl Mbtiles {
}
}

/// Detect the type of the `MBTiles` file.
///
/// See [`MbtType`] for more information.
pub async fn detect_type<T>(&self, conn: &mut T) -> MbtResult<MbtType>
where
for<'e> &'e mut T: SqliteExecutor<'e>,
Expand Down
Loading