lib/relaton/db.rb in relaton-1.7.6 vs lib/relaton/db.rb in relaton-1.7.7

- old
+ new

@@ -8,55 +8,68 @@ class Db # @param global_cache [String] directory of global DB # @param local_cache [String] directory of local DB def initialize(global_cache, local_cache) @registry = Relaton::Registry.instance - @db = open_cache_biblio(global_cache, type: :global) - @local_db = open_cache_biblio(local_cache, type: :local) - @static_db = open_cache_biblio File.expand_path("../relaton/static_cache", __dir__) + gpath = global_cache && File.expand_path(global_cache) + @db = open_cache_biblio(gpath, type: :global) + lpath = local_cache && File.expand_path(local_cache) + @local_db = open_cache_biblio(lpath, type: :local) + @static_db = open_cache_biblio File.expand_path("../relaton/static_cache", + __dir__) @queues = {} end - # Move global and/or local caches to anothe dirs - # @param new_global_dir [String, nil] - # @param new_local_dir [String, nil] - def mv(new_global_dir, new_local_dir) - @db.mv new_global_dir - @local_db.mv new_local_dir + # Move global or local caches to anothe dirs + # @param new_dir [String, nil] + # @param type: [Symbol] + # @return [String, nil] + def mv(new_dir, type: :global) + case type + when :global + @db&.mv new_dir + when :local + @local_db&.mv new_dir + end end # Clear global and local databases def clear - @db.clear - @local_db.clear + @db&.clear + @local_db&.clear end ## # The class of reference requested is determined by the prefix of the code: - # GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for iecbib, + # GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for + # iecbib, # # @param code [String] the ISO standard Code to look up (e.g. "ISO 9000") # @param year [String] the year the standard was published (optional) # # @param opts [Hash] options # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # - # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem, - # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem, - # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem] + # @return [nil, RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, - # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem, - # RelatonW3c::W3cBibliographicItem + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] ## def fetch(code, year = nil, opts = {}) stdclass = standard_class(code) || return processor = @registry.processors[stdclass] - ref = processor.respond_to?(:urn_to_code) ? processor.urn_to_code(code)&.first : code + ref = if processor.respond_to?(:urn_to_code) + processor.urn_to_code(code)&.first + else code + end ref ||= code result = combine_doc ref, year, opts, stdclass result ||= check_bibliocache(ref, year, opts, stdclass) result end @@ -71,13 +84,19 @@ # @param test [String, nil] # @param edition [String], nil # @param year [Integer, nil] # @return [Array] def fetch_all(text = nil, edition: nil, year: nil) - result = @static_db.all { |file, yml| search_yml file, yml, text, edition, year }.compact + result = @static_db.all do |file, yml| + search_yml file, yml, text, edition, year + end.compact db = @db || @local_db - result += db.all { |file, xml| search_xml file, xml, text, edition, year }.compact if db + if db + result += db.all do |file, xml| + search_xml file, xml, text, edition, year + end.compact + end result end # Fetch asynchronously def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength @@ -98,21 +117,22 @@ # @param year [String, NilClass] # @param stdclass [Symbol, NilClass] # # @param opts [Hash] # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # - # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem, - # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem, - # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem] + # @return [nil, RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, - # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem, - # RelatonW3c::W3cBibliographicItem + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] def fetch_std(code, year = nil, stdclass = nil, opts = {}) std = nil @registry.processors.each do |name, processor| std = name if processor.prefix == stdclass end @@ -191,13 +211,15 @@ # @param edition [String, nil] edition to filter # @param year [Integer, nil] year to filter # @return [BibliographicItem, nil] def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity processor = @registry.processors[standard_class(file.split("/")[-2])] - item = file.match?(/xml$/) ? processor.from_xml(content) : processor.hash_to_bib(YAML.safe_load(content)) - item if (edition.nil? || item.edition == edition) && - (year.nil? || item.date.detect { |d| d.type == "published" && d.on(:year) == year }) + item = if file.match?(/xml$/) then processor.from_xml(content) + else processor.hash_to_bib(YAML.safe_load(content)) + end + item if (edition.nil? || item.edition == edition) && (year.nil? || + item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s }) end # @param xml [String] content in XML format # @param text [String, nil] text to serach # @return [Boolean] @@ -209,21 +231,22 @@ # @param year [String, nil] # @param stdslass [String] # # @param opts [Hash] options # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # - # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem, - # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem, - # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem] + # @return [nil, RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, - # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem, - # RelatonW3c::W3cBibliographicItem + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength if (refs = code.split " + ").size > 1 reltype = "derivedFrom" reldesc = nil elsif (refs = code.split ", ").size > 1 @@ -233,15 +256,20 @@ end doc = @registry.processors[stdclass].hash_to_bib docid: { id: code } ref = refs[0] updates = check_bibliocache(ref, year, opts, stdclass) - doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates") if updates + if updates + doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, + type: "updates") + end refs[1..-1].each_with_object(doc) do |c, d| bib = check_bibliocache("#{ref}/#{c}", year, opts, stdclass) if bib - d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib) + d.relation << RelatonBib::DocumentRelation.new( + type: reltype, description: reldesc, bibitem: bib + ) end end end # @param code [String] code of standard @@ -252,12 +280,12 @@ processor.defaultprefix.match(code) end allowed = @registry.processors.reduce([]) do |m, (_k, v)| m << v.prefix end - warn <<~WARN - #{code} does not have a recognised prefix: #{allowed.join(', ')}. + Util.log <<~WARN, :info + [relaton] #{code} does not have a recognised prefix: #{allowed.join(', ')}. See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them. WARN end # TODO: i18n @@ -265,11 +293,12 @@ # @param code [String] # @param year [String] # # @param opts [Hash] # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # # @param stdClass [Symbol] # @return [Array<String>] docid and code def std_id(code, year, opts, stdclass) @@ -290,74 +319,83 @@ [prefix, code] end # @param entry [String] XML string # @param stdclass [Symbol] - # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem, - # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem, - # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem] + # @return [nil, RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, - # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem, - # RelatonW3c::W3cBibliographicItem + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] def bib_retval(entry, stdclass) - entry.nil? || entry.match?(/^not_found/) ? nil : @registry.processors[stdclass].from_xml(entry) + if entry.nil? || entry.match?(/^not_found/) then nil + else @registry.processors[stdclass].from_xml(entry) + end end # @param code [String] # @param year [String] # # @param opts [Hash] # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # # @param stdclass [Symbol] - # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem, - # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem, - # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem] + # @return [nil, RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, - # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem, - # RelatonW3c::W3cBibliographicItem + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity id, searchcode = std_id(code, year, opts, stdclass) yaml = @static_db[id] - return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml) if yaml + if yaml + return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml) + end db = @local_db || @db altdb = @local_db && @db ? @db : nil if db.nil? return if opts[:fetch_db] - bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) + bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db, + id: id) return bib_retval(bibentry, stdclass) end db.delete(id) unless db.valid_entry?(id, year) if altdb return bib_retval(altdb[id], stdclass) if opts[:fetch_db] db.clone_entry id, altdb if altdb.valid_entry? id, year - db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) + db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, + id: id) altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year) else return bib_retval(db[id], stdclass) if opts[:fetch_db] - db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) + db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, + id: id) end bib_retval(db[id], stdclass) end # @param code [String] # @param year [String] # # @param opts [Hash] # @option opts [Boolean] :all_parts If all-parts reference is required - # @option opts [Boolean] :keep_year If undated reference should return actual reference with year + # @option opts [Boolean] :keep_year If undated reference should return + # actual reference with year # @option opts [Integer] :retries (1) Number of network retries # # @param stdclass [Symbol] # @param db [Relaton::DbCache,`NilClass] # @param id [String] docid @@ -365,11 +403,12 @@ def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1)) bib_id = bib&.docidentifier&.first&.id # when docid doesn't match bib's id then return a reference to bib's id - if args[:db] && args[:id] && bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}} + if args[:db] && args[:id] && + bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}} bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first args[:db][bid] ||= bib_entry bib "redirection #{bid}" else bib_entry bib end @@ -382,13 +421,18 @@ raise e unless retries > 1 net_retry(code, year, opts, stdclass, retries - 1) end - # @param bib [RelatonGb::GbBibliongraphicItem, RelatonIsoBib::IsoBibliographicItem, - # RelatonIetf::IetfBibliographicItem, RelatonItu::ItuBibliographicItem, - # RelatonNist::NistBibliongraphicItem, RelatonOgc::OgcBibliographicItem] + # @param bib [RelatonBib::BibliographicItem, + # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem, + # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem, + # RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem, + # RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem, + # RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem, + # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem, + # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem] # @return [String] XML or "not_found mm-dd-yyyy" def bib_entry(bib) if bib.respond_to? :to_xml bib.to_xml(bibdata: true) else @@ -397,21 +441,24 @@ end # @param dir [String, nil] DB directory # @param type [Symbol] # @return [Relaton::DbCache, NilClass] - def open_cache_biblio(dir, type: :static) + def open_cache_biblio(dir, type: :static) # rubocop:disable Metrics/MethodLength return nil if dir.nil? db = DbCache.new dir, type == :static ? "yml" : "xml" return db if type == :static Dir["#{dir}/*/"].each do |fdir| next if db.check_version?(fdir) - FileUtils.rm_rf(Dir.glob(fdir + "/*"), secure: true) - db.set_version fdir - warn "[relaton] cache #{fdir}: version is obsolete and cache is cleared." + FileUtils.rm_rf(fdir, secure: true) + Util.log( + "[relaton] WARNING: cache #{fdir}: version is obsolete and cache is "\ + "cleared.", + :warning + ) end db end # @param qwp [Hash]