diff --git a/.Rbuildignore b/.Rbuildignore index 54336f4..44aa68b 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -16,3 +16,5 @@ Rprof\.out ^scripts$ ^vignettes_src$ ^appveyor\.yml$ +^.*\.Rproj$ +^\.Rproj\.user$ diff --git a/DESCRIPTION b/DESCRIPTION index 4d7b8ef..a3a6179 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -27,5 +27,5 @@ Suggests: rbenchmark, testthat (>= 1.0.0) VignetteBuilder: knitr -RoxygenNote: 6.0.1 +RoxygenNote: 6.1.0 Encoding: UTF-8 diff --git a/R/driver_rds.R b/R/driver_rds.R index bbcbda7..c4ae307 100644 --- a/R/driver_rds.R +++ b/R/driver_rds.R @@ -76,6 +76,16 @@ ##' ##' @param default_namespace Default namespace (see ##' \code{\link{storr}}). +##' +##' @param mangle_key_encode Optional function for mangling keys. +##' Only used if `mangle_key` is `TRUE`. +##' Should accept arguments `key` and `pad`. +##' +##' @param mangle_key_decode Optional function for unmangling keys. +##' Inverse operation of `mangle_key_encode`. +##' Only used if `mangle_key` is `TRUE`. +##' Should accept arguments `key` and `error`. +##' ##' @export ##' @examples ##' @@ -110,16 +120,21 @@ ##' st2$destroy() storr_rds <- function(path, compress = NULL, mangle_key = NULL, mangle_key_pad = NULL, hash_algorithm = NULL, - default_namespace = "objects") { - storr(driver_rds(path, compress, mangle_key, mangle_key_pad, hash_algorithm), + default_namespace = "objects", + mangle_key_encode = NULL, + mangle_key_decode = NULL) { + storr(driver_rds(path, compress, mangle_key, mangle_key_pad, hash_algorithm, + mangle_key_encode, mangle_key_decode), default_namespace) } ##' @export ##' @rdname storr_rds driver_rds <- function(path, compress = NULL, mangle_key = NULL, - mangle_key_pad = NULL, hash_algorithm = NULL) { - R6_driver_rds$new(path, compress, mangle_key, mangle_key_pad, hash_algorithm) + mangle_key_pad = NULL, hash_algorithm = NULL, + mangle_key_encode = NULL, mangle_key_decode = NULL) { + R6_driver_rds$new(path, compress, mangle_key, mangle_key_pad, hash_algorithm, + mangle_key_encode, mangle_key_decode) } R6_driver_rds <- R6::R6Class( @@ -133,10 +148,13 @@ R6_driver_rds <- R6::R6Class( mangle_key = NULL, mangle_key_pad = NULL, hash_algorithm = NULL, + mangle_key_encode = NULL, + mangle_key_decode = NULL, traits = list(accept = "raw"), initialize = function(path, compress, mangle_key, mangle_key_pad, - hash_algorithm) { + hash_algorithm, + mangle_key_encode, mangle_key_decode) { is_new <- !file.exists(file.path(path, "config")) dir_create(path) dir_create(file.path(path, "data")) @@ -157,6 +175,14 @@ R6_driver_rds <- R6::R6Class( write_if_missing("TRUE", driver_rds_config_file(path, "mangle_key_pad")) write_if_missing("TRUE", driver_rds_config_file(path, "compress")) write_if_missing("md5", driver_rds_config_file(path, "hash_algorithm")) + write_if_missing( + deparse(mangle_key_encode), + driver_rds_config_file(path, "mangle_key_encode") + ) + write_if_missing( + deparse(mangle_key_decode), + driver_rds_config_file(path, "mangle_key_decode") + ) } ## Then write out the version number: write_if_missing(as.character(packageVersion("storr")), @@ -175,6 +201,28 @@ R6_driver_rds <- R6::R6Class( driver_rds_config(path, "mangle_key_pad", mangle_key_pad, FALSE, TRUE) + if (!is.null(mangle_key_encode)){ + assert_function(mangle_key_encode) + mangle_key_encode <- deparse(mangle_key_encode) + } + self$mangle_key_encode <- + driver_rds_config(path, "mangle_key_encode", + mangle_key_encode, deparse(encode64), TRUE) + self$mangle_key_encode <- eval( + parse(text = self$mangle_key_encode, keep.source = FALSE) + ) + + if (!is.null(mangle_key_decode)){ + assert_function(mangle_key_decode) + mangle_key_decode <- deparse(mangle_key_decode) + } + self$mangle_key_decode <- + driver_rds_config(path, "mangle_key_decode", + mangle_key_decode, deparse(decode64), TRUE) + self$mangle_key_decode <- eval( + parse(text = self$mangle_key_decode, keep.source = FALSE) + ) + if (!is.null(compress)) { assert_scalar_logical(compress) } @@ -245,7 +293,8 @@ R6_driver_rds <- R6::R6Class( path <- file.path(self$path, "keys", namespace) files <- dir(path) if (self$mangle_key) { - ret <- decode64(files, error = FALSE) + decode_fun <- self$mangle_key_decode %||% decode64 + ret <- decode_fun(files, error = FALSE) if (anyNA(ret)) { message_corrupted_rds_keys(namespace, path, files[is.na(ret)]) ret <- ret[!is.na(ret)] @@ -268,7 +317,8 @@ R6_driver_rds <- R6::R6Class( if (self$mangle_key) { path <- file.path(self$path, "keys", namespace) files <- dir(path) - i <- is.na(decode64(files, error = FALSE)) + decode_fun <- self$mangle_key_decode %||% decode64 + i <- is.na(decode_fun(files, error = FALSE)) if (any(i)) { res <- file.remove(file.path(path, files[i])) message(sprintf("Removed %d of %d corrupt %s", @@ -287,7 +337,8 @@ R6_driver_rds <- R6::R6Class( name_key = function(key, namespace) { if (self$mangle_key) { - key <- encode64(key, pad = self$mangle_key_pad) + encode_fun <- self$mangle_key_encode %||% encode64 + key <- encode_fun(key, pad = self$mangle_key_pad) } file.path(self$path, "keys", namespace, key) } diff --git a/R/driver_remote.R b/R/driver_remote.R index 403e0d2..cc7b0c6 100644 --- a/R/driver_remote.R +++ b/R/driver_remote.R @@ -16,7 +16,8 @@ ##' ##' @param ... Arguments to pass through to \code{\link{driver_rds}}, ##' including \code{compress}, \code{mangle_key}, -##' \code{mangle_key_pad} and \code{hash_algorithm}. +##' \code{mangle_key_pad}, \code{hash_algorithm}, +##' \code{mangle_key_encode}, and \code{mangle_key_decode}. ##' ##' @param path_local Path to a local cache. This can be left as ##' \code{NULL}, in which case a per-session cache will be used. @@ -134,7 +135,7 @@ R6_driver_remote <- R6::R6Class( return(character(0)) } ret <- self$ops$list_dir(path) - if (self$rds$mangle_key) decode64(ret, TRUE) else ret + if (self$rds$mangle_key) self$rds$mangle_key_decode(ret, TRUE) else ret }, ## These functions could be done better if driver_rds takes a diff --git a/R/utils.R b/R/utils.R index 81e93e2..ea2d64e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -103,7 +103,6 @@ assert_raw <- function(x, name = deparse(substitute(x))) { } } - assert_probably_storr_driver <- function(x, name = deparse(substitute(x))) { expected <- c("type", "get_hash", "set_hash", "get_object", "set_object", "exists_hash", "exists_object", diff --git a/man/driver_remote.Rd b/man/driver_remote.Rd index dae2427..570fd16 100644 --- a/man/driver_remote.Rd +++ b/man/driver_remote.Rd @@ -12,7 +12,8 @@ what is required to implement one.} \item{...}{Arguments to pass through to \code{\link{driver_rds}}, including \code{compress}, \code{mangle_key}, -\code{mangle_key_pad} and \code{hash_algorithm}.} +\code{mangle_key_pad}, \code{hash_algorithm}, +\code{mangle_key_encode}, and \code{mangle_key_decode}.} \item{path_local}{Path to a local cache. This can be left as \code{NULL}, in which case a per-session cache will be used. diff --git a/man/storr_rds.Rd b/man/storr_rds.Rd index 4e46782..444599b 100644 --- a/man/storr_rds.Rd +++ b/man/storr_rds.Rd @@ -5,11 +5,14 @@ \alias{driver_rds} \title{rds object cache driver} \usage{ -storr_rds(path, compress = NULL, mangle_key = NULL, mangle_key_pad = NULL, - hash_algorithm = NULL, default_namespace = "objects") +storr_rds(path, compress = NULL, mangle_key = NULL, + mangle_key_pad = NULL, hash_algorithm = NULL, + default_namespace = "objects", mangle_key_encode = NULL, + mangle_key_decode = NULL) driver_rds(path, compress = NULL, mangle_key = NULL, - mangle_key_pad = NULL, hash_algorithm = NULL) + mangle_key_pad = NULL, hash_algorithm = NULL, + mangle_key_encode = NULL, mangle_key_decode = NULL) } \arguments{ \item{path}{Path for the store. \code{tempdir()} is a good choice @@ -38,6 +41,15 @@ values are "md5", "sha1", and others supported by \item{default_namespace}{Default namespace (see \code{\link{storr}}).} + +\item{mangle_key_encode}{Optional function for mangling keys. +Only used if `mangle_key` is `TRUE`. +Should accept arguments `key` and `pad`.} + +\item{mangle_key_decode}{Optional function for unmangling keys. +Inverse operation of `mangle_key_encode`. +Only used if `mangle_key` is `TRUE`. +Should accept arguments `key` and `error`.} } \description{ Object cache driver that saves objects using R's native