Class: MARCSpec::SpecSet

Inherits:
Object
  • Object
show all
Includes:
JLogger::Simple
Defined in:
lib/marcspec/dsl.rb,
lib/marcspec/specset.rb

Overview

A collection of the solr field specifications and maps necessary to turn a MARC record into a set of key=>value pairs suitable for sending to Solr

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSpecSet

Generic new



39
40
41
42
43
# File 'lib/marcspec/specset.rb', line 39

def initialize
  @tmaps = {}
  @solrfieldspecs = []
  @benchmarks = {}
end

Instance Attribute Details

#benchmarksObject

Returns the value of attribute benchmarks.



36
37
38
# File 'lib/marcspec/specset.rb', line 36

def benchmarks
  @benchmarks
end

#solrfieldspecsObject

Returns the value of attribute solrfieldspecs.



36
37
38
# File 'lib/marcspec/specset.rb', line 36

def solrfieldspecs
  @solrfieldspecs
end

#tmapsObject

Returns the value of attribute tmaps.



36
37
38
# File 'lib/marcspec/specset.rb', line 36

def tmaps
  @tmaps
end

Instance Method Details

#add_map(map) ⇒ Object

Add a map to self, using its name (map#mapname) as a key

Parameters:



73
74
75
# File 'lib/marcspec/specset.rb', line 73

def add_map map
  self.tmaps[map.mapname] = map
end

#add_spec(solrfieldspec) ⇒ Object Also known as: <<

Add a spec, making sure there's a slot in the benchmarking stats to keep track of it

Parameters:



143
144
145
146
# File 'lib/marcspec/specset.rb', line 143

def add_spec solrfieldspec
  self.solrfieldspecs << solrfieldspec
  @benchmarks[solrfieldspec.solrField.to_s] = Benchmark::Tms.new(0,0,0,0, 0, solrfieldspec.solrField)      
end

#buildSpecsFromDSLFile(f) ⇒ Object



84
85
86
87
88
89
90
91
92
93
# File 'lib/marcspec/specset.rb', line 84

def buildSpecsFromDSLFile f
  f = File.open(f) if f.is_a? String

  unless f
    log.error("Can't open file #{file}; unable to configure") 
    Process.abort("Can't open file #{file}; unable to configure")
  end
  self.instance_eval(f.read)
  self.check_and_fill_maps
end

#buildSpecsFromList(speclist) ⇒ Object

Deprecated.

Use the DSL

Build a specset from the result of eval'ing an old-style pp hash.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/marcspec/specset.rb', line 114

def buildSpecsFromList speclist
  speclist.each do |spechash|
    if spechash[:module]
      solrspec = MARCSpec::CustomSolrSpec.fromHash(spechash)
    elsif spechash[:constantValue]
      solrspec = MARCSpec::ConstantSolrSpec.fromHash(spechash)
    else
      solrspec = MARCSpec::SolrFieldSpec.fromHash(spechash)
    end
    if spechash[:mapname]
      map = self.map(spechash[:mapname])
      unless map
        log.error "Cannot find map #{spechash[:mapname]} for field #{spechash[:solrField]}"
        Process.abort("Cannot find map #{spechash[:mapname]} for field #{spechash[:solrField]}")
      else
        log.debug "  Found map #{spechash[:mapname]} for field #{spechash[:solrField]}"
        solrspec.map = map
      end
    end
    self.add_spec solrspec
    log.debug "Added spec #{solrspec.solrField}"
  end
end

#check_and_fill_mapsObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/marcspec/specset.rb', line 95

def check_and_fill_maps
  @solrfieldspecs.each do |sfs|
    if sfs._mapname
      map = self.map(sfs._mapname)
      if map
        log.debug "  Found map #{map.mapname} for solr field #{sfs.solrField}"
        sfs.map = map
      else
        log.error "  Cannot find map #{sfs._mapname} for solr field #{sfs.solrField}"
        Process.abort("Cannot find map #{sfs._mapname} for solr field #{sfs.solrField}")
      end
    end
  end
end

#constant(name, &blk) ⇒ Object

Create a constant field



24
25
26
27
28
29
30
31
# File 'lib/marcspec/dsl.rb', line 24

def constant(name, &blk)
  log.debug "Creating constant field #{name}"
  
  constant = ConstantSolrSpec.new(:solrField=>name)
  constant.instance_eval(&blk)
  self << constant
  return constant
end

#custom(name, &blk) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/marcspec/dsl.rb', line 33

def custom(name, &blk)
  log.debug "Creating custom field #{name}"
  custom = CustomSolrSpec.new(:solrField=>name)
  custom.instance_eval(&blk)
  
  ##### Check to make sure it's all ok in here#####
  self << custom
  return custom
end

#doc_from_marc(r, timeit = false) ⇒ SolrInputDocument

Get a new SolrInputDocument based on the record passed in. Statistics will optionally be kept, and can be accessed via the @benchmarks intance varible later on.

Parameters:

  • r (MARC4J4R::Record)

    The record

  • timeit (Boolean) (defaults to: false)

    Whether to keep cumulative benchmarking statistics or not

Returns:

  • (SolrInputDocument)

    Thew new, filled SolrInputDocument



213
214
215
216
217
218
219
220
221
# File 'lib/marcspec/specset.rb', line 213

def doc_from_marc r, timeit = false
  doc = SolrInputDocument.new
  if timeit
    fill_hashlike_from_marc_benchmark r, doc
  else 
    fill_hashlike_from_marc r, doc
  end
  return doc
end

#eachObject

Iterate over each of the solr field specs



152
153
154
155
156
# File 'lib/marcspec/specset.rb', line 152

def each
  @solrfieldspecs.each do |fs|
    yield fs
  end
end

#field(name, &blk) ⇒ Object

create a normal field



15
16
17
18
19
20
21
# File 'lib/marcspec/dsl.rb', line 15

def field(name, &blk)
  log.debug "Creating regular field #{name}"
  sfs = SolrFieldSpec.new(:solrField=>name)
  sfs.instance_eval(&blk)
  self << sfs
  return sfs
end

#fill_hashlike_from_marc(r, hashlike) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/marcspec/specset.rb', line 168

def fill_hashlike_from_marc r, hashlike
  @solrfieldspecs.each do |sfs|
    if sfs.arity == 1
      hashlike.add(sfs.solrField,sfs.marc_values(r, hashlike))
    else 
      vals = sfs.marc_values(r, hashlike)
      (0..(sfs.arity - 1)).each do |i|
        hashlike.add(sfs.solrField[i], vals[i])
      end
    end
  end
end

#fill_hashlike_from_marc_benchmark(r, hashlike) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/marcspec/specset.rb', line 189

def fill_hashlike_from_marc_benchmark r, hashlike
  @solrfieldspecs.each do |sfs|
    @benchmarks[sfs.solrField.to_s] += Benchmark.measure do
      if sfs.arity == 1
        hashlike.add(sfs.solrField,sfs.marc_values(r, hashlike))
      else 
        vals = sfs.marc_values(r, hashlike)
        (0..(sfs.arity - 1)).each do |i|
          hashlike.add(sfs.solrField[i], vals[i])
        end
      end
    end
  end
end

#hash_from_marc(r, timeit = false) ⇒ MockSolrDoc

Exactly the same as #doc_from_marc, but the return object is a subclass of Hash

Parameters:

  • r (MARC4J4R::Record)

    The record

  • timeit (Boolean) (defaults to: false)

    Whether to keep cumulative benchmarking statistics or not

Returns:



230
231
232
233
234
235
236
237
238
# File 'lib/marcspec/specset.rb', line 230

def hash_from_marc r, timeit = false
  h = MARCSpec::MockSolrDoc.new
  if timeit
     fill_hashlike_from_marc_benchmark r, h
   else 
     fill_hashlike_from_marc r, h
   end
  return h
end

#loadMapsFromDir(dir) ⇒ Object

Get all the *.rb files in a directory, assume they're maps, and create entries for them in self

Simple wrapper around MARCSpec::Map#fromFile. Note that if a mapname is not found in the map structure, the name of the file (without the trailing '.rb') will be used.

Parameters:

  • dir (String)

    The directory to look in. Not recursive.



61
62
63
64
65
66
67
68
# File 'lib/marcspec/specset.rb', line 61

def loadMapsFromDir dir
  unless File.exist? dir
    raise ArgumentError, "Cannot load maps from #{dir}: does not exist"
  end
  Dir.glob("#{dir}/*.rb").each do |tmapfile|
    self.add_map(MARCSpec::Map.fromFile(tmapfile))
  end
end

#map(name) ⇒ MARCSpec::Map?

Get the map object associated with the given name

Parameters:

  • name (String)

    The name of the map you want

Returns:



49
50
51
# File 'lib/marcspec/specset.rb', line 49

def map name
  return self.tmaps[name]
end