Class FSDB::Database
In: lib/fsdb/database.rb
lib/fsdb/util.rb
Parent: Object

A thread-safe, process-safe object database class which uses the native file system as its back end and allows multiple file formats.

Methods

Included Modules

Formats PathUtilities DirectoryIterators

Classes and Modules

Class FSDB::Database::AbortedTransaction
Class FSDB::Database::CreateFileError
Class FSDB::Database::DirIsImmutableError
Class FSDB::Database::DirNotEmptyError
Class FSDB::Database::FormatError
Class FSDB::Database::MissingFileError
Class FSDB::Database::MissingObjectError
Class FSDB::Database::NotDirError
Class FSDB::Database::PathComponentError

Constants

MTIME_RESOLUTION = 2.1   On windows, FAT mtime granularity is 2 sec, NTFS is 1 sec.
MTIME_RESOLUTION = 1.1   Even when linux mounts FAT, the mtime granularity is 1 sec.
CLOCK_SKEW = 0.0   in seconds, adjust as needed for stability on NFS
DEFAULT_META_PREFIX = '..fsdb.meta.'   Subclasses can change the defaults.
DEFAULT_LOCK_TYPE = :flock   if RUBY_PLATFORM =~ /darwin/
  DEFAULT_LOCK_TYPE       = :fcntl_lock

else

LOCK_TYPES = [:flock, :fcntl_lock]   These must be methods of File.
FORMATS = [TEXT_FORMAT, MARSHAL_FORMAT].freeze   Subclasses can define their own list of formats, with specified search order

Attributes

dir  [R]  The root directory of the db, to which paths are relative.
lock_type  [R]  The lock type of the db, by default :flock, optionally :fcntl_lock.

Public Class methods

Shortcut to create a new database at path.

Same as abort.

Create a new database object that accesses dir. Makes sure that the directory exists on disk, but doesn’t create or open any other files. The opts hash can include:

:lock_type::flock by default, or :fcntl_lock
:meta_prefix:’..fsdb.meta.’ by default
:formats:nil by default, so the class’s FORMATS is used

Public Instance methods

[](path = "/")

Alias for fetch

[]=(path, object)

Alias for insert

Abort the current transaction (browse, edit, replace, or delete, roll back the state of the object, and return nil from the transaction.

In the browse case, the only effect is to end the transaction.

Note that any exception that breaks out of the transaction will also abort the transaction, and be re-raised.

Convert a relative path (relative to the db dir) to an absolute path.

absolute_path_to(path)

Alias for absolute

Browse the object. Yields the object to the caller’s block, and returns the value of the block.

Changes to the object are not persistent, but should be avoided (they will be seen by other threads, but only in the current process, and only until the cache is cleared). If you return the object from the block, or keep a reference to it in some other way, the object will no longer be protected from concurrent writers.

Can be called occasionally to reduce memory footprint, esp. if cached objects are large and infrequently used.

For housekeeping, so that stale entries don’t result in unused, but uncollectable, CacheEntry objects.

Called when browse doesn’t find anything at the path. The original caller’s block is available to be yielded to.

Called when edit doesn’t find anything at the path. The original caller’s block is available to be yielded to.

Called when fetch doesn’t find anything at the path. Default definition just returns nil.

Delete the object from the db. If a block is given, yields the object (or nil if none) before deleting it from the db (but before releasing the lock on the path), and returns the value of the block. Otherwise, just returns the object (or nil, if none). Raises DirNotEmptyError if path refers to a non-empty dir. If the dir is empty, it is deleted, and the returned value is true. The block is not yielded to. If the load argument is false, delete the object from the db without loading it or yielding, returning true.

Writes object to f (must be open for writing).

Edit the object in place. Changes to the yielded object made within the caller’s block become persistent. Returns the value of the block. Note that assigning to the block argument variable does not change the state of the object. Use destructive methods on the object.

Fetch a copy of the object at the path for private use by the current thread/process. (The copy is a deep copy.)

Note that this is inherently less efficient than browse, because browse leaves the object in the cache, but, for safety, fetch can only return a copy and wipe the cache, since the copy is going to be used outside of any transaction. Subsequent transactions will have to read the object again.

Convert an absolute path to a unique key for the cache, raising MissingFileError if the file does not exist.

path is relative to the database, and initial ’/’ is ignored

Insert the object, replacing anything at the path. Returns the object. (The object remains a local copy, distinct from the one which will be returned when accessing the path through database transactions.)

If path ends in "/", then object is treated as a collection of key-value pairs, and each value is inserted at the corresponding key under path. (You can omit the "/" if the dir already exists.)

  is this still true?

Create a hard link, using File.link. The names are relative to the database’s path.

Returns object read from f (must be open for reading).

Convert an absolute path to a unique key for the cache, creating the file if it does not exist. Raises CreateFileError if it can’t be created.

The default behavior of both default_edit and default_browse. Raises MissingObjectError by default, but it can yield to the original block.

Replace the yielded object (or nil) with the return value of the block. Returns the object that was replaced. No object need exist at path.

Use replace instead of edit when accessing db over a drb connection. Use replace instead of insert if the path needs to be protected while the object is prepared for insertion.

Note that (unlike edit) destructive methods on the object do not persistently change the state of the object, unless the object is the return value of the block.

Create a new database object that accesses path relative to the database directory. A process can have any number of dbs accessing overlapping dirs. The cost of creating an additional db is very low; its state is just the dir and some options. Caching is done in structures owned by the Database class itself.

Create a symbolic link, using File.symlink. The names are relative to the database’s path.

[Validate]