R/clear_cache.R

Defines functions clear_cache_tracts clear_cache_muni

Documented in clear_cache_muni clear_cache_tracts

#' Delete cached CNEFE data files
#'
#' @description
#' `clear_cache_muni()` removes CNEFE data files stored in the user cache
#' directory by [cnefe_counts()], [compute_lumi()], [tracts_to_h3()], and
#' related functions.
#'
#' The cache holds gzipped CSVs (`.csv.gz`). Archives left by versions before
#' 0.3.0, which cached the ZIP as published by IBGE, are removed as well.
#'
#' @param code_muni Integer or `"all"`. If `"all"` (default), every cached CNEFE
#'   file is deleted. If a seven-digit IBGE municipality code is provided, only
#'   the file for that municipality is deleted.
#' @param year Integer. Restrict the deletion to one CNEFE edition. `NULL`
#'   (default) clears every edition, which is the previous behaviour.
#' @param cache_dir Character. Directory to use for cached downloads. If `NULL`
#'   (default), the `CNEFETOOLS_CACHE_DIR` environment variable is used when it
#'   is set, otherwise [tools::R_user_dir()] with `which = "cache"`. Use this to
#'   point large downloads at a secondary drive or a shared volume.
#' @param verbose Logical; if `TRUE` (default), reports the number of files
#'   deleted and the space freed.
#'
#' @return Invisibly, the character vector of deleted file paths.
#'
#' @examples
#' \donttest{
#' # Delete every cached CNEFE file
#' clear_cache_muni()
#'
#' # Delete only the file for Lauro de Freitas-BA
#' clear_cache_muni(2919207)
#' }
#'
#' @export
clear_cache_muni <- function(code_muni = "all", verbose = TRUE, cache_dir = NULL,
                             year = NULL) {
  # Deliberately not .validate_year(): this deletes directories, so it must be
  # able to clear an edition this version no longer reads, or one left behind by
  # a newer version the user downgraded from.
  year <- .cnefe_cache_year(year)
  cache_dir <- .cnefe_cache_dir(cache_dir, year)

  if (!dir.exists(cache_dir)) {
    if (verbose) {
      cli::cli_inform(c("i" = "Cache directory does not exist: {.path {cache_dir}}"))
    }
    return(invisible(character(0)))
  }

  # Both cache formats. `.csv.gz` is what #93 writes; `.zip` is what versions
  # before 0.3.0 left behind, and those still need clearing. Matching only
  # `.zip` made this function a silent no-op after the format changed: it
  # reported an empty cache while every current entry sat there undeleted.
  # `.parquet` is deliberately absent, since census tract assets are
  # clear_cache_tracts()'s business.
  all_files <- list.files(
    path = cache_dir,
    pattern = "\\.(csv\\.gz|zip)$",
    full.names = TRUE,
    # Cache entries live under a directory per CNEFE edition, so clearing
    # every edition (year = NULL) has to recurse to still mean everything.
    recursive = is.null(year)
  )

  if (length(all_files) == 0L) {
    if (verbose) {
      cli::cli_inform(c("i" = "No cached CNEFE files found."))
    }
    return(invisible(character(0)))
  }

  # Filter by municipality code if a specific code was provided
  if (!identical(code_muni, "all")) {
    code_muni <- .normalize_code_muni(code_muni)
    code_str <- as.character(code_muni)
    all_files <- all_files[grepl(code_str, basename(all_files), fixed = TRUE)]

    if (length(all_files) == 0L) {
      if (verbose) {
        cli::cli_inform(c(
          "i" = "No cached file found for municipality {.val {code_muni}}."
        ))
      }
      return(invisible(character(0)))
    }
  }

  # Compute total size before deletion
  sizes <- file.size(all_files)
  total_mb <- sum(sizes, na.rm = TRUE) / 1024^2

  # Delete files
  unlink(all_files)

  if (verbose) {
    n <- length(all_files)
    cli::cli_inform(c(
      "v" = "Deleted {n} cached CNEFE file{?s} ({round(total_mb, 1)} MB freed)."
    ))
  }

  invisible(all_files)
}


#' Delete cached census tract Parquet files
#'
#' @description
#' `clear_cache_tracts()` removes census tract Parquet files stored in the
#' user cache directory by [tracts_to_h3()] and [tracts_to_polygon()].
#'
#' @param uf `"all"`, a two-letter UF abbreviation (e.g. `"BA"`), a two-digit
#'   numeric state code (e.g. `29L`), or a seven-digit IBGE municipality code
#'   (e.g. `2919207`). If `"all"` (default), all cached Parquet files are
#'   deleted. Otherwise, only the file for the resolved state is deleted.
#' @param year Integer. Restrict the deletion to one CNEFE edition. `NULL`
#'   (default) clears every edition, which is the previous behaviour.
#' @param cache_dir Character. Directory to use for cached downloads. If `NULL`
#'   (default), the `CNEFETOOLS_CACHE_DIR` environment variable is used when it
#'   is set, otherwise [tools::R_user_dir()] with `which = "cache"`. Use this to
#'   point large downloads at a secondary drive or a shared volume.
#' @param verbose Logical; if `TRUE` (default), reports the number of files
#'   deleted and the space freed.
#'
#' @return Invisibly, the character vector of deleted file paths.
#'
#' @examples
#' \donttest{
#' # Delete all cached census tract Parquets
#' clear_cache_tracts()
#'
#' # Delete only the Parquet for Bahia (several equivalent calls)
#' clear_cache_tracts("BA")
#' clear_cache_tracts(29)
#' clear_cache_tracts(2919207)  # municipality code → state resolved automatically
#' }
#'
#' @export
clear_cache_tracts <- function(uf = "all", verbose = TRUE, cache_dir = NULL,
                               year = NULL) {
  # Deliberately not .validate_year(): this deletes directories, so it must be
  # able to clear an edition this version no longer reads, or one left behind by
  # a newer version the user downgraded from.
  year <- .cnefe_cache_year(year)
  # Tract assets live at <cache>/<year>/sc_assets, so clearing every edition
  # has to start from the cache root and recurse, not from a single sc_assets.
  sc_dir <- if (is.null(year)) {
    .cnefe_cache_dir(cache_dir)
  } else {
    .sc_cache_dir(cache_dir, year)
  }

  if (!dir.exists(sc_dir)) {
    if (verbose) {
      cli::cli_inform(c("i" = "Cache directory does not exist: {.path {sc_dir}}"))
    }
    return(invisible(character(0)))
  }

  # List all Parquet files
  all_parquets <- list.files(
    path = sc_dir,
    pattern = "\\.parquet$",
    full.names = TRUE,
    # Cache entries live under a directory per CNEFE edition, so clearing
    # every edition (year = NULL) has to recurse to still mean everything.
    recursive = is.null(year)
  )

  if (length(all_parquets) == 0L) {
    if (verbose) {
      cli::cli_inform(c("i" = "No cached census tract Parquet files found."))
    }
    return(invisible(character(0)))
  }

  # Filter by UF if a specific UF was provided
  if (!identical(uf, "all")) {
    uf_code <- .resolve_uf(uf)
    filename <- .sc_asset_filename(uf_code)
    all_parquets <- all_parquets[basename(all_parquets) == filename]

    if (length(all_parquets) == 0L) {
      if (verbose) {
        cli::cli_inform(c(
          "i" = "No cached Parquet found for UF {.val {uf}}."
        ))
      }
      return(invisible(character(0)))
    }
  }

  # Compute total size before deletion
  sizes <- file.size(all_parquets)
  total_mb <- sum(sizes, na.rm = TRUE) / 1024^2

  # Delete files
  unlink(all_parquets)

  if (verbose) {
    n <- length(all_parquets)
    cli::cli_inform(c(
      "v" = "Deleted {n} cached Parquet file{?s} ({round(total_mb, 1)} MB freed)."
    ))
  }

  invisible(all_parquets)
}

Try the cnefetools package in your browser

Any scripts or data that you put into this service are public.

cnefetools documentation built on Oct. 2, 2026, 1:08 a.m.