class Relaton::DbCache

Attributes

dir[R]

@return [String]

Public Class Methods

init_bib_caches(opts) click to toggle source

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

# File lib/relaton/db_cache.rb, line 243
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
new(dir, ext = "xml") click to toggle source

@param dir [String] DB directory

# File lib/relaton/db_cache.rb, line 10
def initialize(dir, ext = "xml")
  @dir = dir
  @ext = ext
  FileUtils::mkdir_p @dir
  # file_version = "#{@dir}/version"
  # set_version # unless File.exist? file_version
end

Private Class Methods

global_bibliocache_name() click to toggle source
# File lib/relaton/db_cache.rb, line 226
def global_bibliocache_name
  "#{Dir.home}/.relaton/cache"
end
local_bibliocache_name(cachename) click to toggle source
# File lib/relaton/db_cache.rb, line 230
def local_bibliocache_name(cachename)
  return nil if cachename.nil?

  cachename = "relaton" if cachename.empty?
  "#{cachename}/cache"
end

Public Instance Methods

[](key) click to toggle source

Read item @param key [String] @return [String]

# File lib/relaton/db_cache.rb, line 66
def [](key)
  value = get(key)
  if (code = redirect? value)
    self[code]
  else
    value
  end
end
[]=(key, value) click to toggle source

Save item @param key [String] @param value [String] Bibitem xml serialization

# File lib/relaton/db_cache.rb, line 41
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
end
all() { |f, content| ... } click to toggle source

Returns all items @return [Array<String>]

# File lib/relaton/db_cache.rb, line 99
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
end
check_version?(fdir) click to toggle source

Check if version of the DB match to the gem grammar hash. @param fdir [String] dir pathe to flover cache @return [TrueClass, FalseClass]

# File lib/relaton/db_cache.rb, line 117
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)
end
clear() click to toggle source

Clear database

# File lib/relaton/db_cache.rb, line 34
def clear
  FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # unless it's static DB
end
clone_entry(key, db) click to toggle source
# File lib/relaton/db_cache.rb, line 75
def clone_entry(key, db)
  self[key] ||= db.get(key)
  if (code = redirect? get(key))
    clone_entry code, db
  end
end
delete(key) click to toggle source

Delete item @param key [String]

# File lib/relaton/db_cache.rb, line 108
def delete(key)
  file = filename key
  f = search_ext(file)
  File.delete f if f
end
ext(value) click to toggle source

@param value [String] @return [String]

# File lib/relaton/db_cache.rb, line 55
def ext(value)
  case value
  when /^not_found/ then "notfound"
  when /^redirection/ then "redirect"
  else @ext
  end
end
fetched(key) click to toggle source

Return fetched date @param key [String] @return [String]

# File lib/relaton/db_cache.rb, line 85
def fetched(key)
  value = self[key]
  return unless value

  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
mv(new_dir) click to toggle source

Move caches to anothe dir @param new_dir [String, nil] @return [String, nil]

# File lib/relaton/db_cache.rb, line 21
def mv(new_dir)
  return unless new_dir && @ext == "xml"

  if File.exist? new_dir
    warn "[relaton] WARNING: target directory exists \"#{new_dir}\""
    return
  end

  FileUtils.mv dir, new_dir
  @dir = new_dir
end
set_version(fdir) click to toggle source

Set version of the DB to the gem grammar hash. @param fdir [String] dir pathe to flover cache @return [Relaton::DbCache]

# File lib/relaton/db_cache.rb, line 128
def set_version(fdir)
  file_version = "#{fdir}/version"
  unless File.exist? file_version
    file_safe_write file_version, grammar_hash(fdir)
  end
  self
end
valid_entry?(key, year) click to toggle source

if cached reference is undated, expire it after 60 days @param key [String] @param year [String]

# File lib/relaton/db_cache.rb, line 139
def valid_entry?(key, year)
  datestr = fetched key
  return false unless datestr

  date = Date.parse datestr
  year || Date.today - date < 60
end

Protected Instance Methods

get(key) click to toggle source

Reads file by a key

@param key [String] @return [String, NilClass]

# File lib/relaton/db_cache.rb, line 160
def get(key)
  file = filename key
  return unless (f = search_ext(file))

  File.read(f, encoding: "utf-8")
end
grammar_hash(fdir) click to toggle source

@param fdir [String] dir pathe to flover cache @return [String]

# File lib/relaton/db_cache.rb, line 151
def grammar_hash(fdir)
  type = fdir.split("/").last
  Relaton::Registry.instance.by_type(type)&.grammar_hash
end

Private Instance Methods

file_safe_write(file, content) click to toggle source

@param file [String] @content [String]

# File lib/relaton/db_cache.rb, line 216
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
filename(key) click to toggle source

Return item's file name @param key [String] @return [String]

# File lib/relaton/db_cache.rb, line 181
def filename(key)
  prefcode = key.downcase.match /^(?<prefix>[^\(]+)\((?<code>[^\)]+)/
  fn = if prefcode
         "#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/\()]/, '_').squeeze('_')}"
       else
         key.gsub(/[-:\s]/, "_")
       end
  "#{@dir}/#{fn.sub(/(,|_$)/, '')}"
end
prefix(key) click to toggle source

Return item's subdir @param key [String] @return [String]

# File lib/relaton/db_cache.rb, line 210
def prefix(key)
  key.downcase.match(/^[^\(]+(?=\()/).to_s
end
redirect?(value) click to toggle source

Check if a file content is redirection

@prarm value [String] file content @return [String, NilClass] redirection code or nil

# File lib/relaton/db_cache.rb, line 173
def redirect?(value)
  %r{redirection\s(?<code>.*)} =~ value
  code
end
search_ext(file) click to toggle source

Checks if there is file with xml or txt extension and return filename with the extension.

@param file [String] @return [String, NilClass]

# File lib/relaton/db_cache.rb, line 197
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