class Sgfa::StoreFs
Stores copies of {History}, {Entry}, and attached files that are in a {Jacket} using filesystem storage.
Storage and retrieval are based on type (i.e. History
, Entry
, or attached file) and the item hash. The item hash is generated from the {Jacket} id_hash, the type, and the specific number. This allows for a single store to serve as the repository of multiple {Jacket}s if desired (e.g. using a cloud permanent object store).
Each item is stored in a file, organized into directories based on the first two characters of the item hash, a file name consisting of the remaining item hash, dash, and a character indicating the type.
Public Class Methods
Create a new store @param path [String] Path to the directory containing the store @raise [Error::Conflict] if path already exists
# File lib/sgfa/store_fs.rb, line 51 def self.create(path) begin Dir.mkdir(path) rescue Errno::EEXIST raise Error::Conflict, 'Store already exists' end end
Public Instance Methods
Close the store
@raise [Error::Sanity] if store is not open @return [StoreFs] self
# File lib/sgfa/store_fs.rb, line 78 def close raise Error::Sanity, 'Store is not open' if !@path @path = nil return self end
Delete an item
@param (see #_fn) @raise [NotImplementedError] if type is not valid @raise [Error::Sanity] if store not open @return [Boolean] if item deleted
# File lib/sgfa/store_fs.rb, line 181 def delete(type, item) raise Error::Sanity, 'Store not open' if !@path fn = _fn(type, item) begin File.unlink(fn) rescue Errno::ENOENT return false end return true end
Open the store
@param path [String] Path to the directory containing the store @raise [Error::NonExistent] if path does not exist @return [StoreFs] self
# File lib/sgfa/store_fs.rb, line 66 def open(path) raise Error::NonExistent, 'Store does not exist' if !File.directory?(path) @path = path return self end
Read an item
@param (see #_fn) @raise [NotImplementedError] if type is not valid @raise [Error::Sanity] if store not open @return [File] Item opened in read only format or false if not found
# File lib/sgfa/store_fs.rb, line 124 def read(type, item) raise Error::Sanity, 'Store not open' if !@path fn = _fn(type, item) begin fi = File.open(fn, 'r', :encoding => 'utf-8') rescue Errno::ENOENT return false end return fi end
Get size of an item in bytes
@param (see #_fn) @raise [NotImplementedError] if type is not valid @raise [Error::Sanity] if store not open @return [Integer, Boolean] Item size, or false if item does not exist
# File lib/sgfa/store_fs.rb, line 201 def size(type, item) fn = _fn(type, item) begin size = File.size(fn) rescue Errno::ENOENT return false end return size end
Get a temp file to use to create an item for storage
@note Encoding on the file is set to ‘utf-8’ by default @raise [Error::Sanity] if store not open @return [Tempfile] the temporary file
# File lib/sgfa/store_fs.rb, line 111 def temp raise Error::Sanity, 'Store not open' if !@path Tempfile.new('blob', @path, :encoding => 'utf-8') end
Write an item
If content is a string, it will be written to a file and saved. If content is a file it will be deleted from it’s current location.
@param (see #_fn) @param cont [File, String] Content to store @raise [Error::Sanity] if store not open @raise [NotImplementedError] if type is not valid
# File lib/sgfa/store_fs.rb, line 147 def write(type, item, cont) raise Error::Sanity, 'Store not open' if !@path fn = _fn(type, item) if cont.is_a?(String) tf = temp tf.write cont cont = tf end begin FileUtils.ln(cont.path, fn, :force => true) rescue Errno::ENOENT Dir.mkdir(File.dirname(fn)) FileUtils.ln(cont.path, fn) end if cont.respond_to?( :close! ) cont.close! else File.unlink(cont, path) cont.close end return self end
Private Instance Methods
File name for an item
@param type [Symbol] Type of the item @param item [String] Item hash identifier @raise [NotImplementedError] if type is not valid @return [String] the file name
# File lib/sgfa/store_fs.rb, line 92 def _fn(type, item) case type when :entry then ext = 'e' when :history then ext = 'h' when :file then ext = 'f' else raise NotImplementedError, 'Invalid item type' end return '%s/%s/%s-%s' % [@path, item[0,2], item[2..-1], ext] end