relaton 1.12.0 → 1.12.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -19
  3. data/docs/README.adoc +18 -3
  4. data/lib/relaton/config.rb +2 -1
  5. data/lib/relaton/db.rb +122 -59
  6. data/lib/relaton/db_cache.rb +40 -73
  7. data/lib/relaton/version.rb +1 -1
  8. data/lib/relaton.rb +1 -0
  9. data/spec/relaton/db_cache_spec.rb +2 -2
  10. data/spec/relaton/db_spec.rb +34 -0
  11. data/spec/relaton/registry_spec.rb +1 -1
  12. data/spec/relaton_spec.rb +38 -1
  13. data/spec/spec_helper.rb +4 -0
  14. data/spec/vcr_cassetes/3gpp_tr_00_01u_umts_3_0_0.yml +17 -16
  15. data/spec/vcr_cassetes/api_relaton_org.yml +56 -0
  16. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +194 -0
  17. data/spec/vcr_cassetes/async_fetch.yml +1325 -1325
  18. data/spec/vcr_cassetes/bipm_i18n_async_fetch.yml +85 -83
  19. data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +17 -13
  20. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +14 -12
  21. data/spec/vcr_cassetes/cie_001_1980.yml +7 -7
  22. data/spec/vcr_cassetes/ecma_6.yml +47 -16
  23. data/spec/vcr_cassetes/en_10160_1999.yml +28 -28
  24. data/spec/vcr_cassetes/fisp_140.yml +6 -6
  25. data/spec/vcr_cassetes/gb_t_20223_2006.yml +79 -9
  26. data/spec/vcr_cassetes/iana_service_names_port_numbers.yml +11 -14
  27. data/spec/vcr_cassetes/iec_60050_102_2007.yml +33 -43
  28. data/spec/vcr_cassetes/iec_combined_included.yml +78 -88
  29. data/spec/vcr_cassetes/ieee_528_2019.yml +44 -2523
  30. data/spec/vcr_cassetes/iho_b_11.yml +10 -10
  31. data/spec/vcr_cassetes/iso_111111119115_1.yml +4 -4
  32. data/spec/vcr_cassetes/iso_19115_1.yml +16 -16
  33. data/spec/vcr_cassetes/iso_19115_1_2.yml +33 -33
  34. data/spec/vcr_cassetes/iso_19115_all_parts.yml +17 -17
  35. data/spec/vcr_cassetes/iso_19133_2005.yml +17 -17
  36. data/spec/vcr_cassetes/iso_combined_applied.yml +32 -32
  37. data/spec/vcr_cassetes/iso_combined_included.yml +33 -33
  38. data/spec/vcr_cassetes/iso_dis_14093.yml +16 -16
  39. data/spec/vcr_cassetes/itu_combined_included.yml +169 -169
  40. data/spec/vcr_cassetes/oasis_amqp_core_types_v1_0_pt1.yml +10 -10
  41. data/spec/vcr_cassetes/ogc_19_025r1.yml +7 -7
  42. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +4 -4
  43. data/spec/vcr_cassetes/rfc_8341.yml +13 -13
  44. data/spec/vcr_cassetes/sp_800_38b.yml +6 -6
  45. data/spec/vcr_cassetes/threads_from_env.yml +56 -56
  46. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +29 -29
  47. data/spec/vcr_cassetes/w3c_json_ld11.yml +20 -20
  48. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb0eb1b1516d3d9891e873ecad6e439da21cb0cf0ef1b13d9f0a53568b04ad6d
4
- data.tar.gz: af692237538c88b588db7537366d0fbc476e92e60f48163f892f0cb254c1fa2d
3
+ metadata.gz: 6e6ac176313825ccd3328f85d357e92a0316dc40af8174f2af9d021ddf00b4e6
4
+ data.tar.gz: 031ab61832bdca69327a65aabd6563c80798488e3292fb272420470bd44e1bb1
5
5
  SHA512:
6
- metadata.gz: 771e6695638f73ee4c6bb4c00d376889ecd5b7120cd9f31e055ab06f3060b24b55e3276f90d74909806b5977f54593cabc201a17729922e2589e5ac1c0fe6ea4
7
- data.tar.gz: 2e9611d5f1b99206a2c99f42720638321781563109e9b0e01345c9576dd6bbd9836c185b55233ea6d7c7ddeaf7c86d90a00605a52ba12d6f9527b7c9a6df5cc0
6
+ metadata.gz: db39780d4edf4de3d7d31b150b5a08161c68f9aa62660e0e55d01bde131e997ca3431204e1f4e6db3826c7183a0df032cb09cda57ae998e681535c10d53c0c5b
7
+ data.tar.gz: bfdb82eb750071772b200ac44d50a5d95019033d4c748483e7bb378b1355c32f8facb0184790da68133dc36018f4386766e6b2739ca9df3d0242e884ba1405ed
@@ -10,23 +10,5 @@ on:
10
10
 
11
11
  jobs:
12
12
  rake:
13
- name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
14
- runs-on: ${{ matrix.os }}
15
- continue-on-error: ${{ matrix.experimental }}
16
- strategy:
17
- fail-fast: false
18
- matrix:
19
- ruby: [ '3.0', '2.7', '2.6' ]
20
- os: [ ubuntu-latest, windows-latest, macos-latest ]
21
- experimental: [ false ]
22
- steps:
23
- - uses: actions/checkout@v2
24
- with:
25
- submodules: true
13
+ uses: relaton/support/.github/workflows/rake.yml@master
26
14
 
27
- - uses: ruby/setup-ruby@v1
28
- with:
29
- ruby-version: ${{ matrix.ruby }}
30
- bundler-cache: true
31
-
32
- - run: bundle exec rake
data/docs/README.adoc CHANGED
@@ -62,6 +62,24 @@ e.g. `get("ISO 19115-1", "2014", all_parts: true)` is transformed into a referen
62
62
 
63
63
  == Usage
64
64
 
65
+ === Configuration
66
+
67
+ * `logs` - is array of log levels. Allowed values: `:info`, `:warning`, `:error`, `:debug`. Default values are `[:info, :error]`.
68
+ * `use_api` - `true` if it needs to use an online cache, `false` inf not. Default value is `true`.
69
+ * `api_host` - url of an online cache. Default value is https://api.relaton.org.
70
+
71
+ [source,ruby]
72
+ ----
73
+ require "relaton"
74
+ => true
75
+
76
+ Relaton.configure do |conf|
77
+ conf.logs = %i[info error]
78
+ conf.use_api = true
79
+ conf.api_host = "https://api.relaton.org"
80
+ end
81
+ ----
82
+
65
83
  === Create DB
66
84
 
67
85
  `Relaton::Db#new(globalcache, localcache)` creates new DB. Returns Relaton::Db instance.
@@ -71,9 +89,6 @@ e.g. `get("ISO 19115-1", "2014", all_parts: true)` is transformed into a referen
71
89
 
72
90
  [source,ruby]
73
91
  ----
74
- require "relaton"
75
- => true
76
-
77
92
  # Do not cache any entries retrieved
78
93
  db = Relaton::Db.new(nil, nil)
79
94
  => #<Relaton::Db:0x007faaaba77648
@@ -12,13 +12,14 @@ module Relaton
12
12
  end
13
13
 
14
14
  class Configuration
15
- attr_accessor :logs, :use_api
15
+ attr_accessor :logs, :use_api, :api_host
16
16
 
17
17
  def initialize
18
18
  @logs = %i(info error) # allowed values: :info, :warning, :error, :debug
19
19
 
20
20
  # @TODO change to true when we start using api.relaton.org
21
21
  @use_api = false
22
+ @api_host = "https://api.relaton.org"
22
23
  end
23
24
  end
24
25
 
data/lib/relaton/db.rb CHANGED
@@ -1,10 +1,4 @@
1
- require "yaml"
2
- require_relative "registry"
3
- require_relative "db_cache"
4
-
5
1
  module Relaton
6
- class RelatonError < StandardError; end
7
-
8
2
  class Db
9
3
  # @param global_cache [String] directory of global DB
10
4
  # @param local_cache [String] directory of local DB
@@ -24,10 +18,8 @@ module Relaton
24
18
  # @return [String, nil]
25
19
  def mv(new_dir, type: :global)
26
20
  case type
27
- when :global
28
- @db&.mv new_dir
29
- when :local
30
- @local_db&.mv new_dir
21
+ when :global then @db&.mv new_dir
22
+ when :local then @local_db&.mv new_dir
31
23
  end
32
24
  end
33
25
 
@@ -69,8 +61,7 @@ module Relaton
69
61
  end
70
62
  ref ||= code
71
63
  result = combine_doc ref, year, opts, stdclass
72
- result ||= check_bibliocache(ref, year, opts, stdclass)
73
- result
64
+ result || check_bibliocache(ref, year, opts, stdclass)
74
65
  end
75
66
 
76
67
  # @see Relaton::Db#fetch
@@ -167,11 +158,7 @@ module Relaton
167
158
  # @param key [String]
168
159
  # @return [Hash]
169
160
  def load_entry(key)
170
- unless @local_db.nil?
171
- entry = @local_db[key]
172
- return entry if entry
173
- end
174
- @db[key]
161
+ (@local_db && @local_db[key]) || @db[key]
175
162
  end
176
163
 
177
164
  # @param key [String]
@@ -187,14 +174,52 @@ module Relaton
187
174
  def to_xml
188
175
  db = @local_db || @db || return
189
176
  Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
190
- xml.documents do
191
- xml.parent.add_child db.all.join(" ")
192
- end
177
+ xml.documents { xml.parent.add_child db.all.join(" ") }
193
178
  end.to_xml
194
179
  end
195
180
 
196
181
  private
197
182
 
183
+ # @param (see #fetch_api)
184
+ # @return (see #fetch_api)
185
+ def fetch_doc(code, year, opts, processor)
186
+ if Relaton.configuration.use_api then fetch_api(code, year, opts, processor)
187
+ else processor.get(code, year, opts)
188
+ end
189
+ end
190
+
191
+ #
192
+ # @param code [String]
193
+ # @param year [String]
194
+ #
195
+ # @param opts [Hash]
196
+ # @option opts [Boolean] :all_parts If all-parts reference is required
197
+ # @option opts [Boolean] :keep_year If undated reference should return
198
+ # actual reference with year
199
+ #
200
+ # @param processor [Relaton::Processor]
201
+ # @return [RelatonBib::BibliographicItem, nil]
202
+ def fetch_api(code, year, opts, processor)
203
+ url = "#{Relaton.configuration.api_host}/api/v1/document?#{params(code, year, opts)}"
204
+ rsp = Net::HTTP.get_response URI(url)
205
+ processor.from_xml rsp.body if rsp.code == "200"
206
+ rescue Errno::ECONNREFUSED
207
+ processor.get(code, year, opts)
208
+ end
209
+
210
+ #
211
+ # Make string of parametrs
212
+ #
213
+ # @param [String] code
214
+ # @param [String] year
215
+ # @param [Hash] opts
216
+ #
217
+ # @return [String]
218
+ #
219
+ def params(code, year, opts)
220
+ opts.merge(code: code, year: year).map { |k, v| "#{k}=#{v}" }.join "&"
221
+ end
222
+
198
223
  # @param file [String] file path
199
224
  # @param xml [String] content in XML format
200
225
  # @param text [String, nil] text to serach
@@ -208,7 +233,7 @@ module Relaton
208
233
  end
209
234
 
210
235
  # @param file [String] file path
211
- # @param content [String] content in XML or YAmL format
236
+ # @param content [String] content in XML or YAML format
212
237
  # @param edition [String, nil] edition to filter
213
238
  # @param year [Integer, nil] year to filter
214
239
  # @return [BibliographicItem, nil]
@@ -221,9 +246,14 @@ module Relaton
221
246
  item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
222
247
  end
223
248
 
249
+ #
250
+ # Look up text in the XML elements attributes and content
251
+ #
224
252
  # @param xml [String] content in XML format
225
253
  # @param text [String, nil] text to serach
254
+ #
226
255
  # @return [Boolean]
256
+ #
227
257
  def match_xml_text(xml, text)
228
258
  %r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
229
259
  end
@@ -258,10 +288,9 @@ module Relaton
258
288
 
259
289
  doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
260
290
  ref = refs[0]
261
- updates = check_bibliocache(ref, year, opts, stdclass)
291
+ updates = check_bibliocache(refs[0], year, opts, stdclass)
262
292
  if updates
263
- doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates,
264
- type: "updates")
293
+ doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates")
265
294
  end
266
295
  divider = stdclass == :relaton_itu ? " " : "/"
267
296
  refs[1..].each_with_object(doc) do |c, d|
@@ -305,8 +334,10 @@ module Relaton
305
334
  [prefix, code]
306
335
  end
307
336
 
308
- # @param entry [String] XML string
337
+ #
338
+ # @param entry [String, nil] XML string
309
339
  # @param stdclass [Symbol]
340
+ #
310
341
  # @return [nil, RelatonBib::BibliographicItem,
311
342
  # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
312
343
  # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
@@ -316,8 +347,8 @@ module Relaton
316
347
  # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
317
348
  # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
318
349
  def bib_retval(entry, stdclass)
319
- if entry.nil? || entry.match?(/^not_found/) then nil
320
- else @registry.processors[stdclass].from_xml(entry)
350
+ if entry && !entry.match?(/^not_found/)
351
+ @registry.processors[stdclass].from_xml(entry)
321
352
  end
322
353
  end
323
354
 
@@ -346,8 +377,7 @@ module Relaton
346
377
  if db.nil?
347
378
  return if opts[:fetch_db]
348
379
 
349
- bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db,
350
- id: id)
380
+ bibentry = new_bib_entry(searchcode, year, opts, stdclass)
351
381
  return bib_retval(bibentry, stdclass)
352
382
  end
353
383
 
@@ -360,54 +390,85 @@ module Relaton
360
390
  @semaphore.synchronize do
361
391
  db.clone_entry id, altdb if altdb.valid_entry? id, year
362
392
  end
363
- entry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) unless db[id]
393
+ new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
364
394
  @semaphore.synchronize do
365
- db[id] ||= entry
366
395
  altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
367
396
  end
368
397
  else
369
398
  return bib_retval(db[id], stdclass) if opts[:fetch_db]
370
399
 
371
- entry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) unless db[id]
372
- @semaphore.synchronize { db[id] ||= entry }
400
+ new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
373
401
  end
374
402
  bib_retval(db[id], stdclass)
375
403
  end
376
404
 
405
+ #
406
+ # Create new bibliographic entry if it doesn't exist in database
407
+ #
377
408
  # @param code [String]
378
409
  # @param year [String]
379
410
  #
380
411
  # @param opts [Hash]
381
- # @option opts [Boolean] :all_parts If all-parts reference is required
382
- # @option opts [Boolean] :keep_year If undated reference should return
383
- # actual reference with year
412
+ # @option opts [Boolean, nil] :all_parts If true then all-parts reference is
413
+ # requested
414
+ # @option opts [Boolean, nil] :keep_year If true then undated reference
415
+ # should return actual reference with year
384
416
  # @option opts [Integer] :retries (1) Number of network retries
385
417
  #
386
418
  # @param stdclass [Symbol]
387
- # @param db [Relaton::DbCache,`NilClass]
388
- # @param id [String] docid
389
- # @return [String]
390
- def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
391
- bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
419
+ # @param db [Relaton::DbCache,`nil]
420
+ # @param id [String, nil] docid
421
+ #
422
+ # @return [String] bibliographic entry
423
+ # XML or "redirection ID" or "not_found YYYY-MM-DD" string
424
+ #
425
+ def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
426
+ entry = @semaphore.synchronize { args[:db] && args[:db][args[:id]] }
427
+ if entry
428
+ if entry&.match?(/^not_found/)
429
+ Util.log "[relaton] (#{code}) not found."
430
+ return
431
+ end
432
+ return entry
433
+ end
434
+
435
+ processor = @registry.processors[stdclass]
436
+ bib = net_retry(code, year, opts, processor, opts.fetch(:retries, 1))
392
437
  bib_id = bib&.docidentifier&.first&.id
393
438
 
394
439
  # when docid doesn't match bib's id then return a reference to bib's id
395
- if args[:db] && args[:id] &&
396
- bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
397
- bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
398
- @semaphore.synchronize { args[:db][bid] ||= bib_entry bib }
399
- "redirection #{bid}"
400
- else bib_entry bib
401
- end
440
+ entry = if args[:db] && args[:id] && bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
441
+ bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
442
+ @semaphore.synchronize { args[:db][bid] ||= bib_entry bib }
443
+ "redirection #{bid}"
444
+ else bib_entry bib
445
+ end
446
+ return entry if args[:db].nil? || args[:id].nil?
447
+
448
+ @semaphore.synchronize { args[:db][args[:id]] ||= entry }
402
449
  end
403
450
 
451
+ #
452
+ # @param code [String]
453
+ # @param year [String]
454
+ #
455
+ # @param opts [Hash]
456
+ # @option opts [Boolean] :all_parts If all-parts reference is required
457
+ # @option opts [Boolean] :keep_year If undated reference should return
458
+ # actual reference with year
459
+ #
460
+ # @param processor [Relaton::Processor]
461
+ # @param retries [Integer] remain Number of network retries
462
+ #
404
463
  # @raise [RelatonBib::RequestError]
405
- def net_retry(code, year, opts, stdclass, retries)
406
- @registry.processors[stdclass].get(code, year, opts)
464
+ # @return [RelatonBib::BibliographicItem]
465
+ #
466
+ def net_retry(code, year, opts, processor, retries)
467
+ fetch_doc code, year, opts, processor
407
468
  rescue RelatonBib::RequestError => e
408
469
  raise e unless retries > 1
409
470
 
410
- net_retry(code, year, opts, stdclass, retries - 1)
471
+ net_retry(code, year, opts, processor, retries - 1)
411
472
  end
412
473
 
413
474
  # @param bib [RelatonBib::BibliographicItem,
@@ -420,11 +481,7 @@ module Relaton
420
481
  # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
421
482
  # @return [String] XML or "not_found mm-dd-yyyy"
422
483
  def bib_entry(bib)
423
- if bib.respond_to? :to_xml
424
- bib.to_xml(bibdata: true)
425
- else
426
- "not_found #{Date.today}"
427
- end
484
+ bib.respond_to?(:to_xml) ? bib.to_xml(bibdata: true) : "not_found #{Date.today}"
428
485
  end
429
486
 
430
487
  # @param dir [String, nil] DB directory
@@ -454,10 +511,16 @@ module Relaton
454
511
  end
455
512
 
456
513
  class << self
514
+ #
457
515
  # Initialse and return relaton instance, with local and global cache names
458
- # local_cache: local cache name; none created if nil; "relaton" created
459
- # if empty global_cache: boolean to create global_cache
460
- # flush_caches: flush caches
516
+ #
517
+ # @param local_cache [String, nil] local cache name;
518
+ # "relaton" created if empty or nil
519
+ # @param global_cache [Boolean, nil] create global_cache if true
520
+ # @param flush_caches [Boolean, nil] flush caches if true
521
+ #
522
+ # @return [Relaton::Db] relaton DB instance
523
+ #
461
524
  def init_bib_caches(**opts) # rubocop:disable Metrics/CyclomaticComplexity
462
525
  globalname = global_bibliocache_name if opts[:global_cache]
463
526
  localname = local_bibliocache_name(opts[:local_cache])
@@ -10,9 +10,7 @@ module Relaton
10
10
  def initialize(dir, ext = "xml")
11
11
  @dir = dir
12
12
  @ext = ext
13
- FileUtils::mkdir_p @dir
14
- # file_version = "#{@dir}/version"
15
- # set_version # unless File.exist? file_version
13
+ FileUtils::mkdir_p dir
16
14
  end
17
15
 
18
16
  # Move caches to anothe dir
@@ -45,7 +43,7 @@ module Relaton
45
43
  end
46
44
 
47
45
  prefix_dir = "#{@dir}/#{prefix(key)}"
48
- FileUtils::mkdir_p prefix_dir unless Dir.exist? prefix_dir
46
+ FileUtils::mkdir_p prefix_dir
49
47
  set_version prefix_dir
50
48
  file_safe_write "#{filename(key)}.#{ext(value)}", value
51
49
  end
@@ -72,6 +70,12 @@ module Relaton
72
70
  end
73
71
  end
74
72
 
73
+ #
74
+ # Save entry from cache of `db` to this cache.
75
+ #
76
+ # @param [String] key key of the entry
77
+ # @param [Relaton::Db] db database
78
+ #
75
79
  def clone_entry(key, db)
76
80
  self[key] ||= db.get(key)
77
81
  if (code = redirect? get(key))
@@ -96,10 +100,10 @@ module Relaton
96
100
 
97
101
  # Returns all items
98
102
  # @return [Array<String>]
99
- def all
103
+ def all(&block)
100
104
  Dir.glob("#{@dir}/**/*.{xml,yml,yaml}").sort.map do |f|
101
105
  content = File.read(f, encoding: "utf-8")
102
- block_given? ? yield(f, content) : content
106
+ block ? yield(f, content) : content
103
107
  end
104
108
  end
105
109
 
@@ -107,30 +111,19 @@ module Relaton
107
111
  # @param key [String]
108
112
  def delete(key)
109
113
  file = filename key
110
- f = search_ext(file)
114
+ f = search_ext file
111
115
  File.delete f if f
112
116
  end
113
117
 
114
118
  # Check if version of the DB match to the gem grammar hash.
115
119
  # @param fdir [String] dir pathe to flover cache
116
- # @return [TrueClass, FalseClass]
120
+ # @return [Boolean]
117
121
  def check_version?(fdir)
118
122
  version_dir = "#{fdir}/version"
119
123
  return false unless File.exist? version_dir
120
124
 
121
125
  v = File.read version_dir, encoding: "utf-8"
122
- v.strip == grammar_hash(fdir)
123
- end
124
-
125
- # Set version of the DB to the gem grammar hash.
126
- # @param fdir [String] dir pathe to flover cache
127
- # @return [Relaton::DbCache]
128
- def set_version(fdir)
129
- file_version = "#{fdir}/version"
130
- unless File.exist? file_version
131
- file_safe_write file_version, grammar_hash(fdir)
132
- end
133
- self
126
+ v.strip == self.class.grammar_hash(fdir)
134
127
  end
135
128
 
136
129
  # if cached reference is undated, expire it after 60 days
@@ -144,15 +137,6 @@ module Relaton
144
137
  year || Date.today - date < 60
145
138
  end
146
139
 
147
- protected
148
-
149
- # @param fdir [String] dir pathe to flover cache
150
- # @return [String]
151
- def grammar_hash(fdir)
152
- type = fdir.split("/").last
153
- Relaton::Registry.instance.by_type(type)&.grammar_hash
154
- end
155
-
156
140
  # Reads file by a key
157
141
  #
158
142
  # @param key [String]
@@ -164,19 +148,16 @@ module Relaton
164
148
  File.read(f, encoding: "utf-8")
165
149
  end
166
150
 
167
- private
168
-
169
- # Check if a file content is redirection
170
- #
171
- # @prarm value [String] file content
172
- # @return [String, NilClass] redirection code or nil
173
- def redirect?(value)
174
- %r{redirection\s(?<code>.*)} =~ value
175
- code
151
+ # @param fdir [String] dir pathe to flover cache
152
+ # @return [String]
153
+ def self.grammar_hash(fdir)
154
+ type = fdir.split("/").last
155
+ Relaton::Registry.instance.by_type(type)&.grammar_hash
176
156
  end
177
157
 
178
- # Return item's file name
179
- # @param key [String]
158
+ private
159
+
160
+ # @param value [String]
180
161
  # @return [String]
181
162
  def filename(key)
182
163
  prefcode = key.downcase.match(/^(?<prefix>[^(]+)\((?<code>[^)]+)/)
@@ -204,13 +185,31 @@ module Relaton
204
185
  end
205
186
  end
206
187
 
207
- # Return item's subdir
188
+ # Set version of the DB to the gem grammar hash.
189
+ # @param fdir [String] dir pathe to flover cache
190
+ def set_version(fdir)
191
+ file_version = "#{fdir}/version"
192
+ unless File.exist? file_version
193
+ file_safe_write file_version, self.class.grammar_hash(fdir)
194
+ end
195
+ end
196
+
197
+ # Return item's file name
208
198
  # @param key [String]
209
199
  # @return [String]
210
200
  def prefix(key)
211
201
  key.downcase.match(/^[^(]+(?=\()/).to_s
212
202
  end
213
203
 
204
+ # Check if a file content is redirection
205
+ #
206
+ # @prarm value [String] file content
207
+ # @return [String, NilClass] redirection code or nil
208
+ def redirect?(value)
209
+ %r{redirection\s(?<code>.*)} =~ value
210
+ code
211
+ end
212
+
214
213
  # @param file [String]
215
214
  # @content [String]
216
215
  def file_safe_write(file, content)
@@ -219,37 +218,5 @@ module Relaton
219
218
  f.write content
220
219
  end
221
220
  end
222
-
223
- class << self
224
- private
225
-
226
- def global_bibliocache_name
227
- "#{Dir.home}/.relaton/cache"
228
- end
229
-
230
- def local_bibliocache_name(cachename)
231
- return nil if cachename.nil?
232
-
233
- cachename = "relaton" if cachename.empty?
234
- "#{cachename}/cache"
235
- end
236
-
237
- public
238
-
239
- # Initialse and return relaton instance, with local and global cache names
240
- # local_cache: local cache name; none created if nil; "relaton" created
241
- # if empty global_cache: boolean to create global_cache
242
- # flush_caches: flush caches
243
- def init_bib_caches(opts) # rubocop:disable Metrics/CyclomaticComplexity
244
- globalname = global_bibliocache_name if opts[:global_cache]
245
- localname = local_bibliocache_name(opts[:local_cache])
246
- localname = "relaton" if localname&.empty?
247
- if opts[:flush_caches]
248
- FileUtils.rm_rf globalname unless globalname.nil?
249
- FileUtils.rm_rf localname unless localname.nil?
250
- end
251
- Relaton::Db.new(globalname, localname)
252
- end
253
- end
254
221
  end
255
222
  end
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "1.12.0".freeze
2
+ VERSION = "1.12.3".freeze
3
3
  end
data/lib/relaton.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "relaton/util"
2
2
  require "relaton/config"
3
+ require "yaml"
3
4
 
4
5
  require "relaton/workers_pool"
5
6
  require "relaton/db"
@@ -6,8 +6,8 @@ RSpec.describe Relaton::DbCache do
6
6
  cache_path = File.expand_path("~/.relaton/cache")
7
7
  FileUtils.mv cache_path, "relaton1/cache", force: true
8
8
  FileUtils.rm_rf %w(relaton)
9
- Relaton::DbCache.init_bib_caches(
10
- global_cache: true, local_cache: "", flush_caches: true
9
+ Relaton::Db.init_bib_caches(
10
+ global_cache: true, local_cache: "", flush_caches: true,
11
11
  )
12
12
  expect(File.exist?(cache_path)).to be true
13
13
  expect(File.exist?("relaton")).to be true
@@ -1,6 +1,40 @@
1
1
  RSpec.describe Relaton::Db do
2
2
  before(:each) { FileUtils.rm_rf %w[testcache testcache2] }
3
3
 
4
+ context "instance methods" do
5
+ subject { Relaton::Db.new nil, nil }
6
+
7
+ context "#search_edition_year" do
8
+ it "create bibitem from YAML content" do
9
+ h = { "docid" => [{ "id" => "ISO 123", type: "ISO", "primary" => true }] }
10
+ expect(YAML).to receive(:safe_load).with(:content).and_return h
11
+ item = subject.send :search_edition_year, "iso/item.yaml", :content, nil, nil
12
+ expect(item).to be_instance_of RelatonIsoBib::IsoBibliographicItem
13
+ end
14
+ end
15
+
16
+ context "#new_bib_entry" do
17
+ it "warn if cached entry is not_found" do
18
+ id = "ISO(ISO 123)"
19
+ db = double "db"
20
+ expect(db).to receive(:[]).with(id).and_return "not_found"
21
+ expect do
22
+ entry = subject.send :new_bib_entry, "ISO 123", nil, {}, :relaton_iso, db: db, id: id
23
+ expect(entry).to be_nil
24
+ end.to output("[relaton] (ISO 123) not found.\n").to_stderr
25
+ end
26
+ end
27
+ end
28
+
29
+ context "class methods" do
30
+ it "::init_bib_caches" do
31
+ expect(FileUtils).to receive(:rm_rf).with(/\/\.relaton\/cache$/)
32
+ expect(FileUtils).to receive(:rm_rf).with(/testcache\/cache$/)
33
+ expect(Relaton::Db).to receive(:new).with(/\/\.relaton\/cache$/, /testcache\/cache$/)
34
+ Relaton::Db.init_bib_caches(global_cache: true, local_cache: "testcache", flush_caches: true)
35
+ end
36
+ end
37
+
4
38
  context "modifing database" do
5
39
  let(:db) { Relaton::Db.new "testcache", "testcache2" }
6
40
 
@@ -2,7 +2,7 @@ RSpec.describe Relaton::Registry do
2
2
  it "outputs backend not present" do
3
3
  stub_const "Relaton::Registry::SUPPORTED_GEMS", ["not_supported_gem"]
4
4
  expect { Relaton::Registry.clone.instance }.to output(
5
- /backend not_supported_gem not present/
5
+ /backend not_supported_gem not present/,
6
6
  ).to_stderr
7
7
  end
8
8