class Moltrio::Config::FileStorage
Attributes
path[R]
Public Class Methods
new(path)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 16 def initialize(path) @path = path end
Public Instance Methods
[](key)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 20 def [](key) if has_key?(key) *path, leaf = splitted_key(key) hamster_to_ruby(traverse(path).fetch(leaf)) else nil end end
[]=(dotted_key, value)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 29 def []=(dotted_key, value) ancestor_keys = splitted_key(dotted_key) current_value = value base_hash = hash while ancestor_keys.any? *ancestor_keys, current_key = ancestor_keys old_value = traverse(ancestor_keys, base_hash: base_hash) current_value = old_value.put(current_key, current_value) end unless @hash.equal?(base_hash) # Retry the change. The hash was updated by other thread while we # were computing the new hash. return self[dotted_key] = value end @hash = current_value save end
has_key?(key)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 52 def has_key?(key) not_found = Object.new value = splitted_key(key).inject(hash) do |current, part| if current.respond_to?(:has_key?) && current.has_key?(part) current[part] else break not_found end end !value.equal?(not_found) end
on_namespace(namespace)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 65 def on_namespace(namespace) scoped(namespace) end
Private Instance Methods
hamster_to_ruby(object)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 119 def hamster_to_ruby(object) return object unless object.kind_of?(Hamster::Hash) object.inject({}) { |hash, (key, value)| hash[key] = hamster_to_ruby(value) hash } end
hash()
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 71 def hash @hash ||= load_from_file end
load_from_file()
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 89 def load_from_file ruby_hash = begin file = File.open(path, "r") file.flock(File::LOCK_SH) YAML.load_file(path) rescue Errno::ENOENT ensure file && file.flock(File::LOCK_UN) end ruby_to_hamster(ruby_hash || {}) rescue Errno::ENOENT Hamster.hash end
ruby_to_hamster(object)
click to toggle source
Not concerned about circular structures here, since this is just for internal usage.
# File lib/moltrio/config/storage/file_storage.rb, line 130 def ruby_to_hamster(object) return object unless object.kind_of?(Hash) object.inject(Hamster.hash) { |hash, (key, value)| hash.put(key, ruby_to_hamster(value)) } end
save()
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 105 def save unless File.exist?(path) FileUtils.mkdir_p(File.dirname(path)) end file = File.open(path, "w") file.flock(File::LOCK_EX) file.write YAML.dump(hamster_to_ruby(hash)) ensure file.flock(File::LOCK_UN) file.close end
splitted_key(key)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 75 def splitted_key(key) key.to_s.split('.') end
traverse(splitted_key, base_hash: hash)
click to toggle source
# File lib/moltrio/config/storage/file_storage.rb, line 79 def traverse(splitted_key, base_hash: hash) splitted_key.inject(base_hash) { |object, current_key| if object.respond_to?(:has_key?) && object.has_key?(current_key) object.fetch(current_key) else break Hamster.hash end } end