Sha256: f9b5612241310bb4306f8780bd2c1dbde01fb542b5b5f160eeaa47b9d5f640b0

Contents?: true

Size: 1.9 KB

Versions: 1

Compression:

Stored size: 1.9 KB

Contents

require 'fileutils'
require 'pathname'

module Metastore
  class Cabinet

    def initialize(file, separators: %w(. /), storage_type: :yaml)
      @file = Pathname.new(file).expand_path
      @separators = separators.map { |x| "\\#{x}" }.join('|')
      @storage_type = storage_type
    end

    def get(key)
      split_key(key).inject(contents) do |c, k|
        c.is_a?(Hash) ? c[k] : nil
      end
    end

    def set(key, value)
      current_contents = contents
      set_key_and_value(current_contents, split_key(key), value)
      save!(current_contents)
    end

    def clear!
      save!({})
    end

    def contents
      storage.contents || {}
    end

    alias [] :get
    alias []= :set

    private

      attr_reader :file, :separators, :storage_type

      def storage
        @store || StorageFactory.from_sym(storage_type).new(file)
      end

      def split_key(key)
        key.to_s.split(Regexp.new(separators))
      end

      def set_key_and_value(input, key, value)
        current_key = key.shift.to_s
        input[current_key] = {} unless input[current_key]

        if key.empty?
          input[current_key] = stringify_keys(value)
          input
        else
          input[current_key] = {} unless input[current_key].is_a?(Hash)
          set_key_and_value(input[current_key], key, value)
        end
      end

      def stringify_keys(input)
        case input
        when Hash
          Hash[
            input.map do |k, v|
              [ k.respond_to?(:to_s) ? k.to_s : k, stringify_keys(v) ]
            end
          ]
        when Enumerable
          input.map { |v| stringify_keys(v) }
        else
          input.is_a?(Symbol) ? input.to_s : input
        end
      end

      def save!(new_values)
        FileUtils.mkdir_p(file.dirname) unless file.exist?
        storage.save!(new_values)
        true
      rescue => e
        raise Errors::CabinetCannotSet, e.message
      end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
metastore-0.4.0 lib/metastore/cabinet.rb