# Start with a write transaction that has written a little data:
env <- thor::mdb_env(tempfile())
txn <- env$begin(write = TRUE)
txn$put("a", "apple")
txn$put("b", "banana")
# We can get a proxy object back by passing as_proxy = TRUE
p <- txn$get("a", as_proxy = TRUE)
p
# Without copying anything we can get the length of the data
p$size() # == nchar("apple")
# And of course we can get the data
p$data()
p$data(as_raw = TRUE)
# Referencing an invalid proxy is an error, but you can use
# "is_valid()" check to see if it is valid
p$is_valid()
txn$put("c", "cabbage")
p$is_valid()
try(p$data())
# It is possible to read the first few bytes; this might be useful
# to determine if (say) a value is a serialised R object:
txn$put("d", serialize(mtcars, NULL))
# The first 6 bytes of a binary serialised rds object is always
#
# 0x58 0x0a 0x00 0x00 0x00 0x02
#
# for XDR serialisation, or
#
# 0x42 0x0a 0x02 0x00 0x00 0x00
#
# for native little-endian serialisation.
#
# So with a little helper function
is_rds <- function(x) {
h_xdr <- as.raw(c(0x58, 0x0a, 0x00, 0x00, 0x00, 0x02))
h_bin <- as.raw(c(0x42, 0x0a, 0x02, 0x00, 0x00, 0x00))
x6 <- head(x, 6L)
identical(x6, h_xdr) || identical(x6, h_bin)
}
# We can see that the value stored at 'a' is not rds
p1 <- txn$get("a", as_proxy = TRUE)
is_rds(p1$head(6, as_raw = TRUE))
# But the value stored at 'd' is:
p2 <- txn$get("d", as_proxy = TRUE)
is_rds(p2$head(6, as_raw = TRUE))
# Retrieve and unserialise the value:
head(unserialize(p2$data()))
Run the code above in your browser using DataLab