lib/relaton/db_cache.rb in relaton-1.7.9 vs lib/relaton/db_cache.rb in relaton-1.8.pre2

- old
+ new

@@ -1,27 +1,27 @@ 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 - FileUtils::mkdir_p @dir - # file_version = "#{@dir}/version" - # set_version # unless File.exist? file_version + @storage = Storage.instance + FileUtils::mkdir_p @dir unless Relaton.configuration.api_mode end # Move caches to anothe dir # @param new_dir [String, nil] # @return [String, nil] def mv(new_dir) - return unless new_dir && @ext == "xml" + return unless new_dir && @ext == "xml" && !Relaton.configuration.api_mode if File.exist? new_dir warn "[relaton] WARNING: target directory exists \"#{new_dir}\"" return end @@ -30,38 +30,29 @@ @dir = new_dir end # Clear database def clear - FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # unless it's static DB + return if Relaton.configuration.api_mode + + FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # if it's static DB end # Save item # @param key [String] # @param value [String] Bibitem xml serialization def []=(key, value) if value.nil? delete key return end - - prefix_dir = "#{@dir}/#{prefix(key)}" - FileUtils::mkdir_p prefix_dir unless Dir.exist? prefix_dir - set_version prefix_dir - file_safe_write "#{filename(key)}.#{ext(value)}", value + /^(?<pref>[^(]+)(?=\()/ =~ key.downcase + prefix_dir = "#{@dir}/#{pref}" + file = "#{filename(key)}.#{ext(value)}" + @storage.save prefix_dir, file, value end - # @param value [String] - # @return [String] - def ext(value) - case value - when /^not_found/ then "notfound" - when /^redirection/ then "redirect" - else @ext - end - end - # Read item # @param key [String] # @return [String] def [](key) value = get(key) @@ -84,57 +75,37 @@ # @return [String] def fetched(key) value = self[key] return unless value - if value.match? /^not_found/ + if value.match?(/^not_found/) value.match(/\d{4}-\d{2}-\d{2}/).to_s else doc = Nokogiri::XML value doc.at("/bibitem/fetched|bibdata/fetched")&.text end end # Returns all items # @return [Array<String>] - def all - Dir.glob("#{@dir}/**/*.{xml,yml,yaml}").sort.map do |f| - content = File.read(f, encoding: "utf-8") - block_given? ? yield(f, content) : content - end + def all(&block) + @storage.all(@dir, &block) end # Delete item # @param key [String] def delete(key) - file = filename key - f = search_ext(file) - File.delete f if f + @storage.delete filename(key) end # Check if version of the DB match to the gem grammar hash. # @param fdir [String] dir pathe to flover cache - # @return [TrueClass, FalseClass] + # @return [Boolean] def check_version?(fdir) - version_dir = fdir + "/version" - return false unless File.exist? version_dir - - v = File.read version_dir, encoding: "utf-8" - v.strip == grammar_hash(fdir) + @storage.check_version? fdir end - # Set version of the DB to the gem grammar hash. - # @param fdir [String] dir pathe to flover cache - # @return [Relaton::DbCache] - def set_version(fdir) - file_version = "#{fdir}/version" - unless File.exist? file_version - file_safe_write file_version, grammar_hash(fdir) - end - self - end - # if cached reference is undated, expire it after 60 days # @param key [String] # @param year [String] def valid_entry?(key, year) datestr = fetched key @@ -142,114 +113,56 @@ date = Date.parse datestr year || Date.today - date < 60 end - protected - - # @param fdir [String] dir pathe to flover cache - # @return [String] - def grammar_hash(fdir) - type = fdir.split("/").last - Relaton::Registry.instance.by_type(type)&.grammar_hash - end - # Reads file by a key # # @param key [String] # @return [String, NilClass] def get(key) - file = filename key - return unless (f = search_ext(file)) - - File.read(f, encoding: "utf-8") + @storage.get filename(key), static: @ext == "yml" end private - # Check if a file content is redirection - # - # @prarm value [String] file content - # @return [String, NilClass] redirection code or nil - def redirect?(value) - %r{redirection\s(?<code>.*)} =~ value - code + # @param value [String] + # @return [String] + def ext(value) + case value + when /^not_found/ then "notfound" + when /^redirection/ then "redirect" + else @ext + end end # Return item's file name # @param key [String] # @return [String] def filename(key) - prefcode = key.downcase.match /^(?<prefix>[^\(]+)\((?<code>[^\)]+)/ + prefcode = key.downcase.match(/^(?<prefix>[^(]+)\((?<code>[^)]+)/) fn = if prefcode - "#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/\()]/, '_').squeeze('_')}" + "#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/()]/, '_') + .squeeze('_')}" else key.gsub(/[-:\s]/, "_") end "#{@dir}/#{fn.sub(/(,|_$)/, '')}" end + # Check if a file content is redirection # - # 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 + # @prarm value [String] file content + # @return [String, NilClass] redirection code or nil + 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 - - class << self - private - - def global_bibliocache_name - "#{Dir.home}/.relaton/cache" - end - - def local_bibliocache_name(cachename) - return nil if cachename.nil? - - cachename = "relaton" if cachename.empty? - "#{cachename}/cache" - end - - public - - # Initialse and return relaton instance, with local and global cache names - # local_cache: local cache name; none created if nil; "relaton" created - # if empty global_cache: boolean to create global_cache - # flush_caches: flush caches - def init_bib_caches(opts) # rubocop:disable Metrics/CyclomaticComplexity - globalname = global_bibliocache_name if opts[:global_cache] - localname = local_bibliocache_name(opts[:local_cache]) - localname = "relaton" if localname&.empty? - if opts[:flush_caches] - FileUtils.rm_rf globalname unless globalname.nil? - FileUtils.rm_rf localname unless localname.nil? - end - Relaton::Db.new(globalname, localname) - end - end + # def prefix(key) + # key.downcase.match(/^[^(]+(?=\()/).to_s + # end end end