data.dump
, and to
decrease the chance of errors from trying to read arbitrary files as
objects, the file name has ".Sdata"
appended to the
object name.
With this definition, every method is a one-line function definition,
and the one utility function, to create the appropriate path name, is
just a call to paste
.
Only the generator function manages to run a little longer, mainly
because it tries to be friendly about creating the directory if it
doesn't exist, and because it stores the full path of the directory.
"database"
and to contain one slot, for the string path name of the corresponding directory.
setClass("dumpDataBase",
representation("database", path = "character"))
"dumpDataBase" =
## make an object of class `"dumpDataBase"' corresponding to the directory
## `path'. The flag `create' allows or suppresses creating the directory if it
## does not exist (by default, the user is asked, if S is in interactive mode).
function(path,
create = identical(dialog(paste("Directory \"", path,
"\"for database does not exist; create?", sep=""), c("y", "n"), 2),1))
{
path = as(path, "character")
if(length(path)!=1) stop("needed a single character string for path")
if(!isDirectory(path)) {
if(create) {
shell(paste("mkdir", path), mustWork=T)
file = paste(path, "objects", sep="/")
cat("", file=file, sep="")
}
else
warning("Directory \"", path,
"\"for database does not exist; path validity not checked")
}
if(isDirectory(path))
## get a fully-qualified path
path = shell(paste("cd", path, "; pwd"))
new("dumpDataBase", path = path)
}
The reason for generating the fully-qualified path is that, otherwise,
the behavior of the database object would depend on the directory in
which the S process is running, very likely not what the user wants.
dbobjects
: Listing the Object Names".Sdata"
, since we decided to write and read
files with that suffix. A small free extension comes from using the
find
shell command: objects can actually be in
subdirectories of the current directory. Their names will have an
embedded "/"
and the simple-minded methods shown here
don't make subdirectories automatically, so the feature is probably
worth about what it costs.
setMethod("dbobjects", "dumpDataBase",
function(database)
shell(paste("find", database@path, "-name '*.Sdata' -print|
sed -e 's:.*/::' -e 's/.Sdata$//'"))
)
dbread
: Read an
ObjectdataPut
, this method just calls dataGet
to do the reading.
setMethod("dbread", "dumpDataBase",
function(database, name)
dataGet(dumpDBPath(database, name))
)
dbwrite
: Write an
ObjectdataPut
function with the path for the given name
.
setMethod("dbwrite", "dumpDataBase",
function(database, name, object)
dataPut(object, dumpDBPath(database, name))
)
dbremove
: Remove an
ObjectsetMethod("dbremove", "dumpDataBase",
function(database, name)
shell(paste("rm '", dumpDBPath(database, name), "'", sep=""), output=F, mustWork=T))
dbexists
: Does an
Object Exist?dbobjects
method returns NULL
; see the
discussion of implementation without a directory.
dumpDBPath = function(database, name)
paste(database@path, "/", name, ".Sdata", sep="")
setClass("dumpFilesDB", representation("dumpDataBase", directory = "logical"))
The only method that needs changing is dbobjects
, which
now returns NULL
if it finds that the
directory
slot is FALSE
.
setMethod("dbobjects", "dumpFilesDB",
function(database)
if(database@directory) shell(paste("find", database@path,
"-name '*.Sdata' -print| sed -e 's/.Sdata$//'"))
else NULL
)