dynarex 1.8.27 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/dynarex.rb +342 -321
  4. data.tar.gz.sig +0 -0
  5. metadata +43 -42
  6. metadata.gz.sig +0 -0
data/lib/dynarex.rb CHANGED
@@ -30,7 +30,7 @@ hkey_gems
30
30
  require dynarex
31
31
  class Dynarex
32
32
  media_type dynarex
33
- '
33
+ '
34
34
  end
35
35
  end
36
36
 
@@ -39,35 +39,35 @@ class DynarexException < Exception
39
39
  end
40
40
 
41
41
  class DynarexRecordset < Array
42
-
42
+
43
43
  def initialize(a, caller=nil)
44
44
  super(a)
45
45
  @caller = caller
46
46
  end
47
-
47
+
48
48
  def reject!()
49
-
49
+
50
50
  a = self.to_a.clone
51
51
  a2 = super
52
52
  return nil unless a2
53
53
  a3 = a - a2
54
-
54
+
55
55
  @caller.delete a3.map(&:id)
56
56
  self
57
57
  end
58
-
58
+
59
59
  def sum(field)
60
60
  self.inject(0) {|r, x| r + x[field.to_sym][/\d+(\.\d+)?$/].to_f }
61
61
  end
62
-
63
- def index(val)
62
+
63
+ def index(val)
64
64
  self.map(&:to_h).index val.to_h
65
65
  end
66
-
67
- def index_by_id(id)
66
+
67
+ def index_by_id(id)
68
68
  self.map(&:id).index id
69
- end
70
-
69
+ end
70
+
71
71
  end
72
72
 
73
73
 
@@ -77,8 +77,8 @@ class Dynarex
77
77
 
78
78
  attr_accessor :format_mask, :delimiter, :xslt_schema, :schema, :linked,
79
79
  :order, :type, :limit, :xslt, :json_out, :unique
80
-
81
-
80
+
81
+
82
82
  #Create a new dynarex document from 1 of the following options:
83
83
  #* a local file path
84
84
  #* a URL
@@ -87,9 +87,9 @@ class Dynarex
87
87
  #* an XML string
88
88
  # Dynarex.new '<contacts><summary><schema>contacts/contact(name,age,dob)</schema></summary><records/></contacts>'
89
89
 
90
- def initialize(rawx=nil, username: nil, password: nil, schema: nil,
91
- default_key: nil, json_out: true, debug: false,
92
- delimiter: ' # ', autosave: false, order: 'ascending',
90
+ def initialize(rawx=nil, username: nil, password: nil, schema: nil,
91
+ default_key: nil, json_out: true, debug: false,
92
+ delimiter: ' # ', autosave: false, order: 'ascending',
93
93
  unique: false, filepath: nil)
94
94
 
95
95
 
@@ -98,7 +98,7 @@ class Dynarex
98
98
  username, password, schema, default_key, json_out, debug
99
99
  @autosave, @unique = autosave, unique
100
100
  @local_filepath = filepath
101
-
101
+
102
102
  puts ('@debug: ' + @debug.inspect).debug if debug
103
103
  @delimiter = delimiter
104
104
  @spaces_delimited = false
@@ -108,12 +108,12 @@ class Dynarex
108
108
  rawx ||= schema if schema
109
109
 
110
110
  if rawx then
111
-
111
+
112
112
  return import(rawx) if rawx =~ /\.txt$/
113
- openx(rawx.clone)
114
-
113
+ openx(rawx.clone)
114
+
115
115
  end
116
-
116
+
117
117
  self.order = @order unless @order.to_sym == :ascending
118
118
 
119
119
  end
@@ -125,17 +125,17 @@ class Dynarex
125
125
  end
126
126
 
127
127
  def all()
128
-
128
+
129
129
  refresh! if @dirty_flag
130
130
  a = @doc.root.xpath("records/*").map {|x| recordx_to_record x}
131
131
  DynarexRecordset.new(a, self)
132
-
132
+
133
133
  end
134
-
134
+
135
135
  def clone()
136
136
  Dynarex.new(self.to_xml)
137
137
  end
138
-
138
+
139
139
  def default_key()
140
140
  self.summary[:default_key]
141
141
  end
@@ -146,10 +146,10 @@ class Dynarex
146
146
  @spaces_delimited = true
147
147
  separator = ' # '
148
148
  end
149
-
149
+
150
150
  @delimiter = separator
151
151
 
152
- if separator.length > 0 then
152
+ if separator.length > 0 then
153
153
  @summary[:delimiter] = separator
154
154
  else
155
155
  @summary.delete :delimiter
@@ -158,14 +158,14 @@ class Dynarex
158
158
  @format_mask = @format_mask.to_s.gsub(/\s/, separator)
159
159
  @summary[:format_mask] = @format_mask
160
160
  end
161
-
161
+
162
162
  def doc
163
163
  (load_records; rebuild_doc) if @dirty_flag == true
164
164
  @doc
165
- end
165
+ end
166
166
 
167
167
  # XML import
168
- #
168
+ #
169
169
  def foreign_import(options={})
170
170
  o = {xml: '', schema: ''}.merge(options)
171
171
  h = {xml: o[:xml], schema: @schema, foreign_schema: o[:schema]}
@@ -174,21 +174,21 @@ class Dynarex
174
174
  openx(buffer)
175
175
  self
176
176
  end
177
-
177
+
178
178
  def fields
179
179
  @fields
180
180
  end
181
-
181
+
182
182
  def first
183
183
  r = @doc.root.element("records/*")
184
- r ? recordx_to_record(r) : nil
184
+ r ? recordx_to_record(r) : nil
185
185
  end
186
186
 
187
187
  def format_mask=(s)
188
188
  @format_mask = s
189
189
  @summary[:format_mask] = @format_mask
190
190
  end
191
-
191
+
192
192
  def insert(raw_params)
193
193
  record = make_record(raw_params)
194
194
  @doc.root.element('records/*').insert_before record
@@ -198,32 +198,32 @@ class Dynarex
198
198
  def inspect()
199
199
  "<object #%s>" % [self.object_id]
200
200
  end
201
-
201
+
202
202
  def linked=(bool)
203
203
  @linked = bool == 'true'
204
204
  end
205
-
205
+
206
206
  def order=(value)
207
-
208
- self.summary.merge!({order: value.to_s})
207
+
208
+ self.summary.merge!({order: value.to_s})
209
209
 
210
210
  @order = value.to_s
211
211
  end
212
-
212
+
213
213
  def recordx_type()
214
214
  @summary[:recordx_type]
215
215
  end
216
-
216
+
217
217
  def schema=(s)
218
218
  openx s
219
219
  end
220
-
220
+
221
221
  def type=(v)
222
222
  @order = 'descending' if v == 'feed'
223
223
  @type = v
224
224
  @summary[:type] = v
225
225
  end
226
-
226
+
227
227
  # Returns the hash representation of the document summary.
228
228
  #
229
229
  def summary
@@ -233,29 +233,29 @@ class Dynarex
233
233
  # Return a Hash (which can be edited) containing all records.
234
234
  #
235
235
  def records
236
-
236
+
237
237
  load_records if @dirty_flag == true
238
-
238
+
239
239
  if block_given? then
240
240
  yield(@records)
241
241
  rebuild_doc
242
- @dirty_flag = true
242
+ @dirty_flag = true
243
243
  else
244
244
  @records
245
245
  end
246
-
246
+
247
247
  end
248
-
249
- # Returns a ready-only snapshot of records as a simple Hash.
248
+
249
+ # Returns a ready-only snapshot of records as a simple Hash.
250
250
  #
251
251
  def flat_records(select: nil)
252
-
252
+
253
253
  fields = select
254
-
254
+
255
255
  load_records if @dirty_flag == true
256
256
 
257
257
  if fields then
258
-
258
+
259
259
  case fields.class.to_s.downcase.to_sym
260
260
  when :string
261
261
  field = fields.to_sym
@@ -267,58 +267,58 @@ class Dynarex
267
267
  @flat_records.map {|row| fields.inject({})\
268
268
  {|r,x| r.merge(x.to_sym => row[x.to_sym])}}
269
269
  end
270
-
270
+
271
271
  else
272
272
  @flat_records
273
273
  end
274
-
274
+
275
275
  end
276
-
276
+
277
277
  alias to_a flat_records
278
-
278
+
279
279
  # Returns an array snapshot of OpenStruct records
280
280
  #
281
281
  def ro_records
282
282
  flat_records.map {|record| OpenStruct.new record }
283
283
  end
284
-
284
+
285
285
  def rm(force: false)
286
-
286
+
287
287
  if force or all.empty? then
288
288
  FileX.rm @local_filepath if @local_filepath
289
289
  'file ' + @local_filepath + ' deleted'
290
290
  else
291
291
  'unable to rm file: document not empty'
292
292
  end
293
-
293
+
294
294
  end
295
-
296
295
 
297
- def to_doc
296
+
297
+ def to_doc
298
298
  self.clone().doc
299
299
  end
300
-
300
+
301
301
  # Typically uses the 1st field as a key and the remaining fields as the value
302
302
  #
303
303
  def to_h()
304
-
304
+
305
305
  key = self.default_key.to_sym
306
306
  fields = self.fields() - [key]
307
307
  puts 'fields: ' + fields.inspect if @debug
308
-
309
- flat_records.inject({}) do |r, h|
310
-
308
+
309
+ flat_records.inject({}) do |r, h|
310
+
311
311
  puts 'h: ' + h.inspect if @debug
312
-
312
+
313
313
  value = if h.length == 2 then
314
314
  h[fields[0]].to_s
315
315
  else
316
- fields.map {|x| h[x]}
316
+ fields.map {|x| h[x]}
317
317
  end
318
-
318
+
319
319
  r.merge(h[key] => value)
320
320
  end
321
-
321
+
322
322
  end
323
323
 
324
324
  def to_html(domain: '')
@@ -327,32 +327,32 @@ class Dynarex
327
327
  xsl_buffer = RXFHelper.read(domain + @xslt, h).first
328
328
  Rexslt.new(xsl_buffer, self.to_doc).to_s
329
329
 
330
- end
331
-
332
-
333
- # to_json: pretty is set to true because although the file size is larger,
330
+ end
331
+
332
+
333
+ # to_json: pretty is set to true because although the file size is larger,
334
334
  # the file can be load slightly quicker
335
-
335
+
336
336
  def to_json(pretty: true)
337
-
337
+
338
338
  records = self.to_a
339
339
  summary = self.summary.to_h
340
-
340
+
341
341
  root_name = schema()[/^\w+/]
342
342
  record_name = schema()[/(?<=\/)[^\(]+/]
343
-
343
+
344
344
  h = {
345
345
  root_name.to_sym =>
346
346
  {
347
347
  summary: @summary,
348
- records: @records.map {|_, h| {record_name.to_sym => h} }
348
+ records: @records.map {|_, h| {record_name.to_sym => h} }
349
349
  }
350
350
  }
351
-
351
+
352
352
  pretty ? JSON.pretty_generate(h) : h.to_json
353
-
353
+
354
354
  end
355
-
355
+
356
356
  def to_s(header: true, delimiter: @delimiter)
357
357
 
358
358
  xsl_buffer =<<EOF
@@ -373,22 +373,22 @@ EOF
373
373
 
374
374
  raw_summary_fields = self.summary[:schema][/^\w+\[([^\]]+)\]/,1]
375
375
  sumry = ''
376
-
376
+
377
377
  if raw_summary_fields then
378
- summary_fields = raw_summary_fields.split(',') # .map(&:to_sym)
378
+ summary_fields = raw_summary_fields.split(',') # .map(&:to_sym)
379
379
  sumry = summary_fields.map {|x| x.strip!; x + ': ' + \
380
380
  self.summary[x.to_sym].to_s}.join("\n") + "\n\n"
381
381
  end
382
-
382
+
383
383
  if @raw_header then
384
384
  declaration = @raw_header
385
385
  else
386
386
 
387
- smry_fields = %i(schema)
387
+ smry_fields = %i(schema)
388
388
  smry_fields << :order if self.summary[:order] == 'descending'
389
-
389
+
390
390
  if delimiter.length > 0 then
391
- smry_fields << :delimiter
391
+ smry_fields << :delimiter
392
392
  else
393
393
  smry_fields << :format_mask unless self.summary[:rawdoc_type] == 'rowx'
394
394
  end
@@ -406,44 +406,44 @@ EOF
406
406
  <xsl:text>\n</xsl:text>%s:<xsl:text> </xsl:text><xsl:value-of select='%s'/>
407
407
  </xsl:if>" % ([field]*3)
408
408
  end
409
-
409
+
410
410
  puts ('a: ' + a.inspect).debug if @debug
411
411
 
412
- xslt_format = a.join
412
+ xslt_format = a.join
413
413
 
414
414
  xsl_buffer.sub!(/\[!regex_values\]/, xslt_format)
415
-
415
+
416
416
  if @debug then
417
417
  File.write '/tmp/foo.xsl', xsl_buffer
418
418
  File.write '/tmp/foo.xml', @doc.xml
419
419
  puts 'xsl_buffer: ' + xsl_buffer.inspect
420
420
  end
421
-
421
+
422
422
  out = Rexslt.new(xsl_buffer, @doc).to_s
423
-
423
+
424
424
  docheader + "\n--+\n" + out
425
- elsif self.summary[:rawdoc_type] == 'sectionx' then
426
-
425
+ elsif self.summary[:rawdoc_type] == 'sectionx' then
426
+
427
427
  a = (self.fields - [:uid, 'uid']).map do |field|
428
428
  "<xsl:if test=\"%s != ''\">
429
429
  <xsl:text>\n</xsl:text><xsl:value-of select='%s'/>
430
430
  </xsl:if>" % ([field]*2)
431
431
  end
432
432
 
433
- xslt_format = a.join
433
+ xslt_format = a.join
434
434
 
435
435
  xsl_buffer.sub!(/\[!regex_values\]/, xslt_format)
436
436
  puts 'xsl_buffer: ' + xsl_buffer.inspect if @debug
437
437
 
438
438
  out = Rexslt.new(xsl_buffer, @doc).to_s
439
-
439
+
440
440
  header ? docheader + "--#\n" + out : out
441
-
441
+
442
442
  elsif self.delimiter.length > 0 then
443
443
  puts 'dinddd'
444
444
  tfo = TableFormatter.new border: false, wrap: false, \
445
445
  divider: self.delimiter
446
- tfo.source = self.to_a.map{|x| x.values}
446
+ tfo.source = self.to_a.map{|x| x.values}
447
447
  docheader + tfo.display.strip
448
448
 
449
449
  else
@@ -454,7 +454,7 @@ EOF
454
454
  s1, s2 = '<xsl:text>', '</xsl:text>'
455
455
  xslt_format = s1 + format_mask\
456
456
  .gsub(/(?:\[!(\w+)\])/, s2 + '<xsl:value-of select="\1"/>' + s1) + s2
457
-
457
+
458
458
  xsl_buffer.sub!(/\[!regex_values\]/, xslt_format)
459
459
 
460
460
  puts 'xsl_buffer: ' + xsl_buffer if @debug
@@ -466,7 +466,7 @@ EOF
466
466
  end
467
467
 
468
468
  def to_table(fields: nil, markdown: false, innermarkdown: false, heading: true)
469
-
469
+
470
470
  tfo = TableFormatter.new markdown: markdown, innermarkdown: innermarkdown
471
471
  tfo.source = self.to_a.map {|h| fields ? fields.map {|x| h[x]} : h.values }
472
472
 
@@ -475,59 +475,59 @@ EOF
475
475
  fields = raw_headings.split(self.delimiter) if raw_headings and fields.nil?
476
476
  tfo.labels = (fields ? fields : self.fields.map{|x| x.to_s.capitalize })
477
477
  end
478
-
478
+
479
479
  tfo
480
-
480
+
481
481
  end
482
-
483
- def to_xml(opt={})
482
+
483
+ def to_xml(opt={})
484
484
  opt = {pretty: true} if opt == :pretty
485
485
  display_xml(opt)
486
486
  end
487
-
488
- # Save the document to a file.
489
-
487
+
488
+ # Save the document to a file.
489
+
490
490
  def save(filepath=@local_filepath, options={})
491
-
491
+
492
492
  if @debug then
493
- puts 'inside Dynarex::save'
493
+ puts 'inside Dynarex::save'
494
494
  puts 'filepath: ' + filepath.inspect
495
495
 
496
496
  end
497
-
497
+
498
498
  return unless filepath
499
-
499
+
500
500
  opt = {pretty: true}.merge options
501
501
 
502
502
  @local_filepath = filepath || 'dx.xml'
503
503
  xml = display_xml(opt)
504
504
  buffer = block_given? ? yield(xml) : xml
505
-
505
+
506
506
  if @debug then
507
507
  puts 'before write; filepath: ' + filepath.inspect
508
508
  puts 'buffer: ' + buffer.inspect
509
509
  end
510
-
510
+
511
511
  FileX.write filepath, buffer
512
512
  FileX.write(filepath.sub(/\.xml$/,'.json'), self.to_json) if @json_out
513
513
  end
514
-
514
+
515
515
  #Parses 1 or more lines of text to create or update existing records.
516
516
 
517
517
  def parse(x=nil)
518
518
 
519
519
  @dirty_flag = true
520
-
520
+
521
521
  if x.is_a? Array then
522
-
522
+
523
523
  unless @schema then
524
- cols = x.first.keys.map {|c| c == 'id' ? 'uid' : c}
524
+ cols = x.first.keys.map {|c| c == 'id' ? 'uid' : c}
525
525
  self.schema = "items/item(%s)" % cols.join(', ')
526
526
  end
527
-
527
+
528
528
  x.each {|record| self.create record }
529
- return self
530
-
529
+ return self
530
+
531
531
  end
532
532
  raw_buffer, type = RXFHelper.read(x, auto: false)
533
533
 
@@ -535,15 +535,15 @@ EOF
535
535
 
536
536
  buffer = block_given? ? yield(raw_buffer) : raw_buffer.clone
537
537
  string_parse buffer
538
-
538
+
539
539
  else
540
540
  foreign_import x
541
541
  end
542
-
543
- end
542
+
543
+ end
544
544
 
545
545
 
546
- alias import parse
546
+ alias import parse
547
547
 
548
548
  #Create a record from a hash containing the field name, and the field value.
549
549
  # dynarex = Dynarex.new 'contacts/contact(name,age,dob)'
@@ -553,8 +553,8 @@ EOF
553
553
 
554
554
  puts 'inside create' if @debug
555
555
  raise 'Dynarex#create(): input error: no arg provided' unless obj
556
-
557
- case obj.class.to_s.downcase.to_sym
556
+
557
+ case obj.class.to_s.downcase.to_sym
558
558
  when :hash
559
559
  hash_create obj, id, attr: custom_attributes
560
560
  when :string
@@ -566,7 +566,7 @@ EOF
566
566
  end
567
567
 
568
568
  @dirty_flag = true
569
-
569
+
570
570
  puts 'before save ' + @autosave.inspect if @debug
571
571
  save() if @autosave
572
572
 
@@ -575,13 +575,13 @@ EOF
575
575
 
576
576
  #Create a record from a string, given the dynarex document contains a format mask.
577
577
  # dynarex = Dynarex.new 'contacts/contact(name,age,dob)'
578
- # dynarex.create_from_line 'Tracy 37 15-Jun-1972'
579
-
578
+ # dynarex.create_from_line 'Tracy 37 15-Jun-1972'
579
+
580
580
  def create_from_line(line, id=nil, attr: '')
581
581
  t = @format_mask.to_s.gsub(/\[!(\w+)\]/, '(.*)').sub(/\[/,'\[')\
582
582
  .sub(/\]/,'\]')
583
583
  line.match(/#{t}/).captures
584
-
584
+
585
585
  a = line.match(/#{t}/).captures
586
586
  h = Hash[@fields.zip(a)]
587
587
  create h
@@ -596,8 +596,8 @@ EOF
596
596
 
597
597
 
598
598
  #Updates a record from an id and a hash containing field name and field value.
599
- # dynarex.update 4, name: Jeff, age: 38
600
-
599
+ # dynarex.update 4, name: Jeff, age: 38
600
+
601
601
  def update(id, obj)
602
602
 
603
603
  params = if obj.is_a? Hash then
@@ -605,32 +605,32 @@ EOF
605
605
  elsif obj.is_a? RecordX
606
606
  obj.to_h
607
607
  end
608
-
608
+
609
609
  fields = capture_fields(params)
610
610
 
611
611
  # for each field update each record field
612
- record = @doc.root.element("records/#{@record_name}[@id='#{id.to_s}']")
612
+ record = @doc.root.element("records/#{@record_name}[@id='#{id.to_s}']")
613
613
 
614
614
  fields.each do |k,v|
615
615
  puts "updating ... %s = '%s'" % [k,v] if @debug
616
616
  record.element(k.to_s).text = v if v
617
617
  end
618
-
618
+
619
619
  record.add_attribute(last_modified: Time.now.to_s)
620
620
 
621
621
  @dirty_flag = true
622
622
 
623
623
  save() if @autosave
624
-
624
+
625
625
  self
626
626
 
627
627
  end
628
628
 
629
-
629
+
630
630
  #Delete a record.
631
631
  # dyarex.delete 3 # deletes record with id 3
632
-
633
- def delete(x)
632
+
633
+ def delete(x)
634
634
 
635
635
  return x.each {|id| self.delete id} if x.is_a? Array
636
636
 
@@ -639,86 +639,86 @@ EOF
639
639
  else
640
640
  @doc.delete x
641
641
  end
642
-
642
+
643
643
  @dirty_flag = true
644
644
  save() if @autosave
645
-
645
+
646
646
  self
647
647
  end
648
648
 
649
649
  def element(x)
650
650
  @doc.root.element x
651
- end
652
-
651
+ end
652
+
653
653
  def sort_by!(field=nil, &element_blk)
654
654
 
655
655
  blk = field ? ->(x){ x.text(field.to_s).to_s} : element_blk
656
656
  r = sort_records_by! &blk
657
- @dirty_flag = true
657
+ @dirty_flag = true
658
658
  r
659
659
 
660
- end
660
+ end
661
+
661
662
 
662
-
663
663
  def record(id)
664
- e = @doc.root.element("records/*[@id='#{id}']")
664
+ e = @doc.root.element("records/*[@id='#{id}']")
665
665
  recordx_to_record e if e
666
666
  end
667
-
667
+
668
668
  alias find record
669
669
  alias find_by_id record
670
670
 
671
671
  def record_exists?(id)
672
672
  !@doc.root.element("records/*[@id='#{id}']").nil?
673
673
  end
674
-
674
+
675
675
  def refresh()
676
676
  @dirty_flag = true
677
677
  end
678
-
678
+
679
679
  def refresh!()
680
- (load_records; rebuild_doc) if @dirty_flag == true
680
+ (load_records; rebuild_doc) if @dirty_flag == true
681
681
  end
682
-
682
+
683
683
  # used internally by to_rss()
684
684
  #
685
685
  def rss_xslt(opt={})
686
-
686
+
687
687
  h = {limit: 11}.merge(opt)
688
688
  doc = Rexle.new(self.to_xslt)
689
689
  e = doc.element('//xsl:apply-templates[2]')
690
-
690
+
691
691
  e2 = doc.root.element('xsl:template[3]')
692
692
  item = e2.element('item')
693
693
  new_item = item.deep_clone
694
694
  item.delete
695
-
695
+
696
696
  pubdate = @xslt_schema[/pubDate:/]
697
697
  xslif = Rexle.new("<xsl:if test='position() &lt; #{h[:limit]}'/>").root
698
698
 
699
699
  if pubdate.nil? then
700
700
  pubdate = Rexle.new("<pubDate><xsl:value-of select='pubDate'>" + \
701
701
  "</xsl:value-of></pubDate>").root
702
- new_item.add pubdate
702
+ new_item.add pubdate
703
703
  end
704
704
 
705
- xslif.add new_item
705
+ xslif.add new_item
706
706
  e2.add xslif.root
707
- xslt = doc.xml
707
+ xslt = doc.xml
708
+
709
+ xslt
708
710
 
709
- xslt
710
-
711
711
  end
712
-
712
+
713
713
  def filter(&blk)
714
-
714
+
715
715
  dx = Dynarex.new @schema
716
716
  self.all.select(&blk).each {|x| dx.create x}
717
717
  dx
718
-
718
+
719
719
  end
720
720
 
721
- def to_xslt(opt={})
721
+ def to_xslt(opt={})
722
722
 
723
723
  h = {limit: -1}.merge(opt)
724
724
  @xslt_schema = @xslt_schema || self.summary[:xslt_schema]
@@ -728,47 +728,47 @@ EOF
728
728
 
729
729
  return xslt
730
730
  end
731
-
731
+
732
732
  def to_rss(opt={}, xslt=nil)
733
-
733
+
734
734
  puts 'inside to_rss'.info if @debug
735
-
735
+
736
736
  unless xslt then
737
-
737
+
738
738
  h = {limit: 11}.merge(opt)
739
739
  doc = Rexle.new(self.to_xslt)
740
740
  e = doc.element('//xsl:apply-templates[2]')
741
-
741
+
742
742
  e2 = doc.root.element('xsl:template[3]')
743
743
  item = e2.element('item')
744
744
  new_item = item.deep_clone
745
745
  item.delete
746
-
746
+
747
747
  pubdate = @xslt_schema[/pubDate:/]
748
748
  xslif = Rexle.new("<xsl:if test='position() &lt; #{h[:limit]}'/>").root
749
-
750
-
749
+
750
+
751
751
  if pubdate.nil? then
752
752
  pubdate2 = Rexle.new("<pubDate><xsl:value-of select='pubDate'></xsl:value-of></pubDate>").root
753
- new_item.add pubdate2
753
+ new_item.add pubdate2
754
754
  end
755
755
 
756
- xslif.add new_item
756
+ xslif.add new_item
757
757
  e2.add xslif
758
- xslt = doc.xml
758
+ xslt = doc.xml
759
759
 
760
760
  xslt
761
761
  end
762
-
762
+
763
763
  doc = Rexle.new(self.to_xml)
764
-
764
+
765
765
  puts ('pubdate: ' + pubdate.inspect).debug if @debug
766
-
766
+
767
767
  if pubdate.nil? then
768
768
  doc.root.xpath('records/*').each do |x|
769
769
  raw_dt = DateTime.parse x.attributes[:created]
770
770
  dt = raw_dt.strftime("%a, %d %b %Y %H:%M:%S %z")
771
- x.add Rexle::Element.new('pubDate').add_text dt.to_s
771
+ x.add Rexle::Element.new('pubDate').add_text dt.to_s
772
772
  end
773
773
  end
774
774
 
@@ -776,7 +776,7 @@ EOF
776
776
  File.write '/tmp/blog.xml', doc.root.xml
777
777
  puts ('xslt:' + xslt.inspect) if @debug
778
778
  File.write '/tmp/blog.xslt', xslt
779
-
779
+
780
780
  out = Rexslt.new(xslt, doc).to_s(declaration: false)
781
781
 
782
782
  #Rexle.new("<rss version='2.0'>%s</rss>" % xml).xml(pretty: true)
@@ -786,23 +786,23 @@ EOF
786
786
  xml = doc.xml(pretty: true)
787
787
  xml
788
788
  end
789
-
789
+
790
790
  def unique=(bool)
791
791
  self.summary.merge!({unique: bool})
792
792
  @dirty_flag = true
793
793
  @unique = bool
794
794
  end
795
-
795
+
796
796
  def xpath(x)
797
797
  @doc.root.xpath x
798
798
  end
799
799
 
800
800
  def xslt=(value)
801
-
801
+
802
802
  self.summary.merge!({xslt: value})
803
803
  @dirty_flag = true
804
804
  @xslt = value
805
- end
805
+ end
806
806
 
807
807
  private
808
808
 
@@ -810,7 +810,7 @@ EOF
810
810
  @default_key = :uid
811
811
  @summary[:default_key] = 'uid'
812
812
  @fields << :uid
813
- a.each.with_index{|x,i| x << (i+1).to_s}
813
+ a.each.with_index{|x,i| x << (i+1).to_s}
814
814
  end
815
815
 
816
816
  def create_find(fields)
@@ -823,21 +823,42 @@ EOF
823
823
  end
824
824
 
825
825
  def findx_by(field, value)
826
+
826
827
  #@logger.debug "field: #{field.inspect}, value: #{value.inspect}"
827
828
  (load_records; rebuild_doc) if @dirty_flag == true
828
- r = @doc.root.element("records/*[#{field}=\"#{value}\"]")
829
- r ? recordx_to_record(r) : nil
829
+
830
+ if value.is_a? String then
831
+
832
+ r = @doc.root.element("records/*[#{field}=\"#{value}\"]")
833
+ r ? recordx_to_record(r) : nil
834
+
835
+ elsif value.is_a? Regexp
836
+
837
+ found = all.select {|x| x.method(field).call =~ /#{value}/i}
838
+ found.first if found.any?
839
+
840
+ end
841
+
830
842
  end
831
843
 
832
844
  def findx_all_by(field, value)
833
- @doc.root.xpath("records/*[#{field}=\"#{value}\"]")\
845
+
846
+ if value.is_a? String then
847
+
848
+ @doc.root.xpath("records/*[#{field}=\"#{value}\"]")\
834
849
  .map {|x| recordx_to_record x}
850
+
851
+ elsif value.is_a? Regexp
852
+
853
+ all.select {|x| x.method(field).call =~ /#{value}/i}
854
+
855
+ end
835
856
  end
836
857
 
837
858
  def recordx_to_record(recordx)
838
-
859
+
839
860
  h = recordx.attributes
840
-
861
+
841
862
  records = recordx.xpath("*").map {|x| x.text ? x.text.unescape.to_s : '' }
842
863
  hash = @fields.zip(records).to_h
843
864
  RecordX.new(hash, self, h[:id], h[:created], h[:last_modified])
@@ -859,21 +880,21 @@ EOF
859
880
  fields.keys.each {|key| fields[key] = params[key.to_sym] if params.has_key? key.to_sym}
860
881
  fields
861
882
  end
862
-
883
+
863
884
  def display_xml(options={})
864
885
  #@logger.debug 'inside display_xml'
865
886
  opt = {unescape_html: false}.merge options
866
-
887
+
867
888
  state = :external
868
889
  #@logger.debug 'before diry'
869
890
  if @dirty_flag == true then
870
- load_records
891
+ load_records
871
892
  state = :internal
872
893
  end
873
894
  #@logger.debug 'before rebuilt'
874
895
  doc = rebuild_doc(state)
875
896
  #@logger.debug 'after rebuild_doc'
876
-
897
+
877
898
  if opt[:unescape_html] == true then
878
899
  doc.content(opt)
879
900
  else
@@ -887,15 +908,15 @@ EOF
887
908
  raw_params.merge!(uid: id) if @default_key.to_sym == :uid
888
909
  params = Hash[raw_params.keys.map(&:to_sym).zip(raw_params.values)]
889
910
 
890
- fields = capture_fields(params)
911
+ fields = capture_fields(params)
891
912
  record = Rexle::Element.new @record_name
892
913
 
893
914
  fields.each do |k,v|
894
- element = Rexle::Element.new(k.to_s)
915
+ element = Rexle::Element.new(k.to_s)
895
916
  element.root.text = v.to_s.gsub('<','&lt;').gsub('>','&gt;') if v
896
917
  record.add element if record
897
918
  end
898
-
919
+
899
920
  attributes = {id: id.to_s, created: Time.now.to_s, last_modified: nil}\
900
921
  .merge attr
901
922
  attributes.each {|k,v| record.add_attribute(k, v)}
@@ -912,7 +933,7 @@ EOF
912
933
  buffer = RXFHelper.read(line.chomp, auto: false).first
913
934
 
914
935
  doc = Rexle.new buffer
915
-
936
+
916
937
  if doc.root.name == 'kvx' then
917
938
 
918
939
  kvx = Kvx.new doc
@@ -924,17 +945,17 @@ EOF
924
945
  end
925
946
 
926
947
  end
927
-
948
+
928
949
  def rebuild_doc(state=:internal)
929
-
950
+
930
951
  puts 'inside rebuild_doc'.info if @debug
931
952
 
932
- reserved_keywords = (
953
+ reserved_keywords = (
933
954
  Object.public_methods | \
934
955
  Kernel.public_methods | \
935
956
  public_methods + [:method_missing]
936
957
  )
937
-
958
+
938
959
  xml = RexleBuilder.new
939
960
 
940
961
  a = xml.send @root_name do
@@ -960,30 +981,30 @@ EOF
960
981
  #jr160315records.reverse! if @order == 'descending' and state == :external
961
982
 
962
983
  xml.records do
963
-
984
+
964
985
  records.each do |k, item|
965
-
986
+
966
987
  attributes = {}
967
-
988
+
968
989
  item.keys.each do |key|
969
990
  attributes[key] = item[key] || '' unless key == :body
970
991
  end
971
-
992
+
972
993
  if @record_name.nil? then
973
994
  raise DynarexException, 'record_name can\'t be nil. Check the schema'
974
995
  end
975
-
996
+
976
997
  xml.send(@record_name, attributes) do
977
- item[:body].each do |name,value|
998
+ item[:body].each do |name,value|
978
999
 
979
1000
  if reserved_keywords.include? name then
980
- name = ('._' + name.to_s).to_sym
1001
+ name = ('._' + name.to_s).to_sym
981
1002
  end
982
-
1003
+
983
1004
  val = value.send(value.is_a?(String) ? :to_s : :to_yaml)
984
1005
  xml.send(name, val.gsub('>','&gt;')\
985
1006
  .gsub('<','&lt;')\
986
- .gsub(/(&\s|&[a-zA-Z\.]+;?)/) do |x|
1007
+ .gsub(/(&\s|&[a-zA-Z\.]+;?)/) do |x|
987
1008
  x[-1] == ';' ? x : x.sub('&','&amp;')
988
1009
  end
989
1010
  )
@@ -998,22 +1019,22 @@ EOF
998
1019
  end
999
1020
 
1000
1021
  doc = Rexle.new(a)
1001
-
1022
+
1002
1023
  puts ('@xslt: ' + @xslt.inspect).debug if @debug
1003
-
1024
+
1004
1025
  if @xslt then
1005
- doc.instructions = [['xml-stylesheet',
1026
+ doc.instructions = [['xml-stylesheet',
1006
1027
  "title='XSL_formatting' type='text/xsl' href='#{@xslt}'"]]
1007
1028
  end
1008
1029
 
1009
1030
  return doc if state != :internal
1010
1031
  @doc = doc
1011
- end
1012
-
1032
+ end
1033
+
1013
1034
  def string_parse(buffer)
1014
-
1035
+
1015
1036
  if @spaces_delimited then
1016
- buffer = buffer.lines.map{|x| x.gsub(/\s{2,}/,' # ')}.join
1037
+ buffer = buffer.lines.map{|x| x.gsub(/\s{2,}/,' # ')}.join
1017
1038
  end
1018
1039
 
1019
1040
  buffer.gsub!("\r",'')
@@ -1024,25 +1045,25 @@ EOF
1024
1045
  buffer.gsub!(/<./) {|x| x[1] != '?' ? x.sub(/</,'&lt;') : x }
1025
1046
 
1026
1047
  @raw_header = buffer[/<\?dynarex[^>]+>/]
1027
-
1048
+
1028
1049
  if buffer[/<\?/] then
1029
1050
 
1030
1051
  raw_stylesheet = buffer.slice!(/<\?xml-stylesheet[^>]+>/)
1031
1052
  @xslt = raw_stylesheet[/href=["']([^"']+)/,1] if raw_stylesheet
1032
1053
  @raw_header = buffer.slice!(/<\?dynarex[^>]+>/) + "\n"
1033
-
1054
+
1034
1055
  header = @raw_header[/<?dynarex (.*)?>/,1]
1035
1056
 
1036
1057
  r1 = /([\w\-]+\s*\=\s*'[^']*)'/
1037
1058
  r2 = /([\w\-]+\s*\=\s*"[^"]*)"/
1038
1059
 
1039
- r = header.scan(/#{r1}|#{r2}/).map(&:compact).flatten
1060
+ r = header.scan(/#{r1}|#{r2}/).map(&:compact).flatten
1040
1061
 
1041
1062
  r.each do |x|
1042
1063
 
1043
1064
  attr, val = x.split(/\s*=\s*["']/,2)
1044
1065
  name = (attr + '=').to_sym
1045
-
1066
+
1046
1067
  if self.public_methods.include? name then
1047
1068
  self.method(name).call(unescape val)
1048
1069
  else
@@ -1062,7 +1083,7 @@ EOF
1062
1083
  if raw_summary then
1063
1084
 
1064
1085
  a_summary = raw_summary.split(',').map(&:strip)
1065
-
1086
+
1066
1087
  @summary ||= {}
1067
1088
  raw_lines.shift while raw_lines.first.strip.empty?
1068
1089
 
@@ -1082,7 +1103,7 @@ EOF
1082
1103
  @summary[:schema] = @schema
1083
1104
  @summary[:format_mask] = @format_mask
1084
1105
  @summary[:unique] = @unique if @unique
1085
-
1106
+
1086
1107
  raw_lines.shift while raw_lines.first.strip.empty?
1087
1108
 
1088
1109
  lines = case raw_lines.first.rstrip
@@ -1092,10 +1113,10 @@ EOF
1092
1113
  yaml = YAML.load raw_lines.join("\n")
1093
1114
 
1094
1115
  yamlize = lambda {|x| (x.is_a? Array) ? x.to_yaml : x}
1095
-
1116
+
1096
1117
  yprocs = {
1097
1118
  Hash: lambda {|y|
1098
- y.map do |k,v|
1119
+ y.map do |k,v|
1099
1120
  procs = {Hash: proc {|x| x.values}, Array: proc {v}}
1100
1121
  values = procs[v.class.to_s.to_sym].call(v).map(&yamlize)
1101
1122
  [k, *values]
@@ -1104,23 +1125,23 @@ EOF
1104
1125
  Array: lambda {|y| y.map {|x2| x2.map(&yamlize)} }
1105
1126
  }
1106
1127
 
1107
- yprocs[yaml.class.to_s.to_sym].call yaml
1108
-
1128
+ yprocs[yaml.class.to_s.to_sym].call yaml
1129
+
1109
1130
  when '--+'
1110
1131
 
1111
1132
  rowx(raw_lines)
1112
-
1133
+
1113
1134
  when '--#'
1114
1135
 
1115
1136
  self.summary[:rawdoc_type] = 'sectionx'
1116
1137
  raw_lines.shift
1117
1138
 
1118
1139
  raw_lines.join.lstrip.split(/(?=^#[^#])/).map {|x| [x.rstrip]}
1119
-
1140
+
1120
1141
  else
1121
1142
 
1122
1143
  raw_lines = raw_lines.join("\n").gsub(/^(\s*#[^\n]+|\n)/,'').lines.to_a
1123
-
1144
+
1124
1145
  if @linked then
1125
1146
 
1126
1147
  parse_links(raw_lines)
@@ -1129,42 +1150,42 @@ EOF
1129
1150
  a2 = raw_lines.map.with_index do |x,i|
1130
1151
 
1131
1152
  next if x[/^\s+$|\n\s*#/]
1132
-
1153
+
1133
1154
  begin
1134
-
1155
+
1135
1156
  field_names, field_values = RXRawLineParser.new(@format_mask).parse(x)
1136
1157
  rescue
1137
1158
  raise "input file parser error at line " + (i + 1).to_s + ' --> ' + x
1138
1159
  end
1139
1160
  field_values
1140
1161
  end
1141
-
1162
+
1142
1163
  a2.compact!
1143
1164
  a3 = a2.compact.map(&:first)
1144
-
1165
+
1145
1166
  if a3 != a3.uniq then
1146
-
1167
+
1147
1168
  if @unique then
1148
1169
  raise DynarexException, "Duplicate id found"
1149
1170
  else
1150
- add_id(a2)
1171
+ add_id(a2)
1151
1172
  end
1152
-
1173
+
1153
1174
  end
1154
-
1175
+
1155
1176
  a2
1156
- end
1177
+ end
1157
1178
 
1158
1179
  end
1159
1180
 
1160
- a = lines.map.with_index do |x,i|
1161
-
1181
+ a = lines.map.with_index do |x,i|
1182
+
1162
1183
  created = Time.now.to_s
1163
1184
 
1164
1185
  h = Hash[
1165
1186
  @fields.zip(
1166
1187
  x.map do |t|
1167
-
1188
+
1168
1189
  t.to_s[/^---(?:\s|\n)/] ? YAML.load(t[/^---(?:\s|\n)(.*)/,1]) : unescape(t.to_s)
1169
1190
  end
1170
1191
  )
@@ -1186,12 +1207,12 @@ EOF
1186
1207
  item[:body].each do |k,v|
1187
1208
  h[key][:body][k.to_sym] = v
1188
1209
  end
1189
- else
1210
+ else
1190
1211
  item[:id] = (@order == 'descending' ? (h2.count) - i : i+ 1).to_s
1191
1212
  i += 1
1192
1213
  h[key] = item.clone
1193
- end
1194
- end
1214
+ end
1215
+ end
1195
1216
 
1196
1217
  h.each {|key, item| h.delete(key) if not h2.has_key? key}
1197
1218
 
@@ -1200,9 +1221,9 @@ EOF
1200
1221
  rebuild_doc
1201
1222
  self
1202
1223
  end
1203
-
1224
+
1204
1225
  def sort_records_by!(&element_blk)
1205
-
1226
+
1206
1227
  refresh_doc
1207
1228
  a = @doc.root.xpath('records/*').sort_by &element_blk
1208
1229
  @doc.root.delete('records')
@@ -1215,33 +1236,33 @@ EOF
1215
1236
 
1216
1237
  load_records if @dirty_flag
1217
1238
  self
1218
- end
1239
+ end
1219
1240
 
1220
1241
  def unescape(s)
1221
1242
  s.gsub('&lt;', '<').gsub('&gt;','>')
1222
1243
  end
1223
1244
 
1224
1245
  def dynarex_new(s, default_key: nil)
1225
-
1246
+
1226
1247
  @schema = schema = s
1227
1248
  @default_key = default_key if default_key
1228
-
1249
+
1229
1250
  ptrn = %r((\w+)\[?([^\]]+)?\]?\/(\w+)\(([^\)]+)\))
1230
1251
 
1231
1252
  if s.match(ptrn) then
1232
-
1233
- @root_name, raw_summary, record_name, raw_fields = s.match(ptrn).captures
1253
+
1254
+ @root_name, raw_summary, record_name, raw_fields = s.match(ptrn).captures
1234
1255
  summary, fields = [raw_summary || '',raw_fields].map {|x| x.split(/,/).map &:strip}
1235
-
1256
+
1236
1257
  if fields.include? 'id' then
1237
- raise 'Dynarex#dynarex_new: schema field id is a reserved keyword'
1258
+ raise 'Dynarex#dynarex_new: schema field id is a reserved keyword'
1238
1259
  end
1239
-
1260
+
1240
1261
  create_find fields
1241
-
1262
+
1242
1263
  reserved = %w(require parent)
1243
1264
  raise 'reserved keyword' if (fields & reserved).any?
1244
-
1265
+
1245
1266
  else
1246
1267
  ptrn = %r((\w+)\[?([^\]]+)?\]?)
1247
1268
  @root_name, raw_summary = s.match(ptrn).captures
@@ -1264,36 +1285,36 @@ EOF
1264
1285
  def attach_record_methods()
1265
1286
  create_find @fields
1266
1287
  end
1267
-
1288
+
1268
1289
  def openx(s)
1269
1290
  #@logger.debug 'inside openx'
1270
1291
  if s[/</] then # xml
1271
1292
  #@logger.debug 'regular string'
1272
1293
  #@logger.debug 's: ' + s.inspect
1273
1294
  buffer = s
1274
-
1295
+
1275
1296
  elsif s[/[\[\(]/] # schema
1276
1297
 
1277
1298
  dynarex_new(s)
1278
-
1299
+
1279
1300
  elsif s[/^https?:\/\//] then # url
1280
- buffer, type = RXFHelper.read s, {username: @username,
1281
- password: @password, auto: false}
1282
- elsif s[/^dfs?:\/\//] then
1283
-
1284
- @local_filepath = s
1301
+ buffer, type = RXFHelper.read s, {username: @username,
1302
+ password: @password, auto: false}
1303
+ elsif s[/^dfs?:\/\//] then
1304
+
1305
+ @local_filepath = s
1285
1306
 
1286
1307
  if FileX.exists? s then
1287
1308
  buffer = FileX.read s
1288
1309
  elsif @schema
1289
- dynarex_new @schema, default_key: @default_key
1290
- end
1291
-
1310
+ dynarex_new @schema, default_key: @default_key
1311
+ end
1312
+
1292
1313
  else # local file
1293
-
1314
+
1294
1315
  @local_filepath = s
1295
-
1296
- if File.exists? s then
1316
+
1317
+ if File.exists? s then
1297
1318
  buffer = File.read s
1298
1319
  elsif @schema
1299
1320
  dynarex_new @schema, default_key: @default_key
@@ -1302,18 +1323,18 @@ EOF
1302
1323
  end
1303
1324
  end
1304
1325
  #@logger.debug 'buffer: ' + buffer[0..120]
1305
-
1326
+
1306
1327
  return import(buffer) if buffer =~ /^<\?dynarex\b/
1307
1328
 
1308
1329
  if buffer then
1309
1330
 
1310
1331
  raw_stylesheet = buffer.slice!(/<\?xml-stylesheet[^>]+>/)
1311
1332
  @xslt = raw_stylesheet[/href=["']([^"']+)/,1] if raw_stylesheet
1312
-
1313
- @doc = Rexle.new(buffer) unless @doc
1333
+
1334
+ @doc = Rexle.new(buffer) unless @doc
1314
1335
  #@logger.debug 'openx/@doc : ' + @doc.xml.inspect
1315
1336
  end
1316
-
1337
+
1317
1338
  return if @doc.root.nil?
1318
1339
  e = @doc.root.element('summary')
1319
1340
 
@@ -1322,20 +1343,20 @@ EOF
1322
1343
  @summary = summary_to_h
1323
1344
 
1324
1345
  summary_methods = (@summary.keys - self.public_methods)
1325
-
1346
+
1326
1347
  summary_methods.each do |x|
1327
-
1348
+
1328
1349
  instance_eval "
1329
-
1350
+
1330
1351
  def #{x.to_sym}()
1331
1352
  @summary[:#{x}]
1332
1353
  end
1333
-
1354
+
1334
1355
  def #{x.to_s}=(v)
1335
1356
  @summary[:#{x}] = v
1336
1357
  @doc.root.element('summary/#{x.to_s}').text = v
1337
1358
  end
1338
- "
1359
+ "
1339
1360
  end
1340
1361
 
1341
1362
  @order = @summary[:order] if @summary.has_key? :order
@@ -1357,7 +1378,7 @@ EOF
1357
1378
 
1358
1379
  if @fields then
1359
1380
 
1360
- @default_key = @fields[0] unless @default_key
1381
+ @default_key = @fields[0] unless @default_key
1361
1382
  # load the record query handler methods
1362
1383
  attach_record_methods
1363
1384
  else
@@ -1365,46 +1386,46 @@ EOF
1365
1386
  #jr080912 @default_key = @doc.root.xpath('records/*/*').first.name
1366
1387
  @default_key = @doc.root.element('records/./.[1]').name
1367
1388
  end
1368
-
1389
+
1369
1390
  @summary[:default_key] = @default_key.to_s
1370
-
1391
+
1371
1392
  if @doc.root.xpath('records/*').length > 0 then
1372
- @record_name = @doc.root.element('records/*[1]').name
1393
+ @record_name = @doc.root.element('records/*[1]').name
1373
1394
  #jr240913 load_records
1374
1395
  @dirty_flag = true
1375
1396
  end
1376
1397
 
1377
- end
1398
+ end
1378
1399
 
1379
1400
  def load_records
1380
-
1401
+
1381
1402
  puts 'inside load_records'.info if @debug
1382
-
1403
+
1383
1404
  @dirty_flag = false
1384
-
1405
+
1385
1406
  if @summary[:order] then
1386
- orderfield = @summary[:order][/(\w+)\s+(?:ascending|descending)/,1]
1407
+ orderfield = @summary[:order][/(\w+)\s+(?:ascending|descending)/,1]
1387
1408
  sort_records_by! {|x| x.element(orderfield).text } if orderfield
1388
1409
  end
1389
-
1410
+
1390
1411
  @records = records_to_h
1391
-
1412
+
1392
1413
  @records.instance_eval do
1393
1414
  def delete_item(i)
1394
1415
  self.delete self.keys[i]
1395
1416
  end
1396
1417
  end
1397
-
1418
+
1398
1419
  #Returns a ready-only snapshot of records as a simple Hash.
1399
1420
  @flat_records = @records.values.map{|x| x[:body]}
1400
1421
 
1401
1422
  end
1402
-
1423
+
1403
1424
 
1404
1425
  def display()
1405
1426
  puts @doc.to_s
1406
1427
  end
1407
-
1428
+
1408
1429
  def records_to_h(order=:ascending)
1409
1430
 
1410
1431
  i = @doc.root.xpath('max(records/*/attribute::id)') || 0
@@ -1425,25 +1446,25 @@ EOF
1425
1446
  end
1426
1447
 
1427
1448
  body = (@fields - ['uid']).inject({}) do |r,field|
1428
-
1449
+
1429
1450
  node = row.element field.to_s
1430
1451
 
1431
1452
  if node then
1432
1453
  text = node.text ? node.text.unescape : ''
1433
1454
 
1434
- r.merge node.name.to_sym => (text[/^---(?:\s|\n)/] ?
1455
+ r.merge node.name.to_sym => (text[/^---(?:\s|\n)/] ?
1435
1456
  YAML.load(text[/^---(?:\s|\n)(.*)/,1]) : text)
1436
1457
  else
1437
1458
  r
1438
1459
  end
1439
1460
  end
1440
-
1461
+
1441
1462
  body[:uid] = id if @default_key == 'uid'
1442
1463
 
1443
1464
  attributes = row.attributes
1444
1465
  result.merge body[@default_key.to_sym] => attributes.merge({id: id, body: body})
1445
1466
  end
1446
-
1467
+
1447
1468
  puts 'records_to_h a: ' + a.inspect if @debug
1448
1469
  #@logger.debug 'a: ' + a.inspect
1449
1470
  a
@@ -1459,56 +1480,56 @@ EOF
1459
1480
 
1460
1481
  # get the fields
1461
1482
  a4 = a3.map{|x| x.scan(/^\w+(?=:)/)}.flatten(1).uniq
1462
-
1483
+
1463
1484
  abbrv_fields = a4.all? {|x| x.length == 1}
1464
-
1485
+
1465
1486
  a5 = a3.map do |xlines|
1466
-
1487
+
1467
1488
  puts 'xlines: ' + xlines.inspect if @debug
1468
-
1489
+
1469
1490
  missing_fields = a4 - xlines.scan(/^\w+(?=:)/)
1470
1491
 
1471
1492
  r = xlines.split(/\n(\w+:.*)/m)
1472
1493
  puts 'r: ' + r.inspect if @debug
1473
-
1494
+
1474
1495
  missing_fields.map!{|x| x + ":"}
1475
1496
  key = (abbrv_fields ? @fields[0].to_s[0] : @fields.first.to_s) + ':'
1476
-
1497
+
1477
1498
  if missing_fields.include? key
1478
1499
  r.unshift key
1479
1500
  missing_fields.delete key
1480
1501
  end
1481
-
1502
+
1482
1503
  r += missing_fields
1483
1504
  r.join("\n")
1484
-
1505
+
1485
1506
  end
1486
1507
  puts 'a5: ' + a5.inspect if @debug
1487
-
1508
+
1488
1509
  xml = RowX.new(a5.join("\n").strip, level: 0).to_xml
1489
1510
  puts 'xml: ' + xml.inspect if @debug
1490
-
1491
- a2 = Rexle.new(xml).root.xpath('item').inject([]) do |r,x|
1511
+
1512
+ a2 = Rexle.new(xml).root.xpath('item').inject([]) do |r,x|
1492
1513
 
1493
1514
  r << @fields.map do |field|
1494
1515
  x.text(abbrv_fields ? field.to_s.chr : field.to_s )
1495
1516
  end
1496
-
1517
+
1497
1518
  end
1498
1519
 
1499
- a2.compact!
1500
-
1501
- # if there is no field value for the first field then
1520
+ a2.compact!
1521
+
1522
+ # if there is no field value for the first field then
1502
1523
  # the default_key is invalid. The default_key is changed to an ID.
1503
1524
  if a2.detect {|x| x.first == ''} then
1504
1525
  add_id(a2)
1505
1526
  else
1506
1527
 
1507
1528
  a3 = a2.map(&:first)
1508
- add_id(a2) if a3 != a3.uniq
1509
-
1529
+ add_id(a2) if a3 != a3.uniq
1530
+
1510
1531
  end
1511
-
1532
+
1512
1533
  a2
1513
1534
 
1514
1535
  end
@@ -1544,13 +1565,13 @@ XSL
1544
1565
  @doc = Rexle.new(Rexslt.new(xsl, self.to_xml).to_s)
1545
1566
  @dirty_flag = true
1546
1567
  end
1547
-
1568
+
1548
1569
  def summary_to_h
1549
1570
 
1550
1571
  h = {recordx_type: 'dynarex'}
1551
-
1572
+
1552
1573
  @doc.root.xpath('summary/*').inject(h) do |r,node|
1553
- r.merge node.name.to_s.to_sym =>
1574
+ r.merge node.name.to_s.to_sym =>
1554
1575
  node.text ? node.text.unescape : node.text.to_s
1555
1576
  end
1556
1577
  end