lib/relaton/db_cache.rb in relaton-1.8.pre3 vs lib/relaton/db_cache.rb in relaton-1.8.pre4

- old
+ new

@@ -1,27 +1,25 @@ require "fileutils" require "timeout" -require "relaton/storage" module Relaton class DbCache # @return [String] attr_reader :dir # @param dir [String] DB directory def initialize(dir, ext = "xml") @dir = dir @ext = ext - @storage = Storage.instance - FileUtils::mkdir_p @dir unless Relaton.configuration.api_mode + FileUtils::mkdir_p dir end # Move caches to anothe dir # @param new_dir [String, nil] # @return [String, nil] def mv(new_dir) - return unless new_dir && @ext == "xml" && !Relaton.configuration.api_mode + return unless new_dir && @ext == "xml" if File.exist? new_dir warn "[relaton] WARNING: target directory exists \"#{new_dir}\"" return end @@ -30,13 +28,11 @@ @dir = new_dir end # Clear database def clear - return if Relaton.configuration.api_mode - - FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # if it's static DB + FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # if it isn't a static DB end # Save item # @param key [String] # @param value [String] Bibitem xml serialization @@ -45,12 +41,13 @@ delete key return end /^(?<pref>[^(]+)(?=\()/ =~ key.downcase prefix_dir = "#{@dir}/#{pref}" - file = "#{filename(key)}.#{ext(value)}" - @storage.save prefix_dir, file, value + FileUtils::mkdir_p prefix_dir unless Dir.exist? prefix_dir + set_version prefix_dir + file_safe_write "#{filename(key)}.#{ext(value)}", value end # Read item # @param key [String] # @return [String] @@ -86,24 +83,33 @@ end # Returns all items # @return [Array<String>] def all(&block) - @storage.all(@dir, &block) + Dir.glob("#{@dir}/**/*.{xml,yml,yaml}").sort.map do |f| + content = File.read(f, encoding: "utf-8") + block ? yield(f, content) : content + end end # Delete item # @param key [String] def delete(key) - @storage.delete filename(key) + file = filename key + f = search_ext file + File.delete f if f end # Check if version of the DB match to the gem grammar hash. # @param fdir [String] dir pathe to flover cache # @return [Boolean] def check_version?(fdir) - @storage.check_version? fdir + version_file = "#{fdir}/version" + return false unless File.exist? version_file + + v = File.read version_file, encoding: "utf-8" + v.strip == self.class.grammar_hash(fdir) end # if cached reference is undated, expire it after 60 days # @param key [String] # @param year [String] @@ -118,13 +124,23 @@ # Reads file by a key # # @param key [String] # @return [String, NilClass] def get(key) - @storage.get filename(key), static: @ext == "yml" + file = filename key + return unless (f = search_ext(file)) + + File.read(f, encoding: "utf-8") end + # @param fdir [String] dir pathe to flover cache + # @return [String] + def self.grammar_hash(fdir) + type = fdir.split("/").last + Relaton::Registry.instance.by_type(type)&.grammar_hash + end + private # @param value [String] # @return [String] def ext(value) @@ -133,10 +149,35 @@ when /^redirection/ then "redirect" else @ext end end + # + # Checks if there is file with xml or txt extension and return filename with + # the extension. + # + # @param file [String] + # @return [String, NilClass] + def search_ext(file) + if File.exist?("#{file}.#{@ext}") + "#{file}.#{@ext}" + elsif File.exist? "#{file}.notfound" + "#{file}.notfound" + elsif File.exist? "#{file}.redirect" + "#{file}.redirect" + end + end + + # Set version of the DB to the gem grammar hash. + # @param fdir [String] dir pathe to flover cache + def set_version(fdir) + file_version = "#{fdir}/version" + unless File.exist? file_version + file_safe_write file_version, self.class.grammar_hash(fdir) + end + end + # Return item's file name # @param key [String] # @return [String] def filename(key) prefcode = key.downcase.match(/^(?<prefix>[^(]+)\((?<code>[^)]+)/) @@ -156,13 +197,15 @@ def redirect?(value) %r{redirection\s(?<code>.*)} =~ value code end - # Return item's subdir - # @param key [String] - # @return [String] - # def prefix(key) - # key.downcase.match(/^[^(]+(?=\()/).to_s - # end + # @param file [String] + # @content [String] + def file_safe_write(file, content) + File.open file, File::RDWR | File::CREAT, encoding: "UTF-8" do |f| + Timeout.timeout(10) { f.flock File::LOCK_EX } + f.write content + end + end end end