Class: DxLite

Inherits:
Object
  • Object
show all
Includes:
RXFReadWriteModule
Defined in:
lib/dxlite.rb

Overview

DxLite can perform the following:

  • read or write an XML file

  • read or write a JSON file (in Dynarex format)

  • import an Array of records (Hash objects)

note: It cannot read a Dynarex file in

the raw Dynarex format (.txt plain text)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(s = nil, autosave: false, order: 'ascending', debug: false) ⇒ DxLite

Returns a new instance of DxLite.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/dxlite.rb', line 28

def initialize(s=nil, autosave: false, order: 'ascending', debug: false)

  @autosave, @debug = autosave, debug

  return unless s
  buffer, type = RXFReader.read(s)

  @filepath = s if type == :file or type == :dfs

  puts 'type: ' + type.inspect if @debug
  puts 'buffer: ' + buffer.inspect if @debug

  @records = []

  case type

  when :dfs

    read buffer

  when :file

    read buffer

  when :text

    new_summary(s, order)

  when :url

    read buffer

  end

end

Instance Attribute Details

#filepathObject

Returns the value of attribute filepath.



25
26
27
# File 'lib/dxlite.rb', line 25

def filepath
  @filepath
end

#recordsObject (readonly)

Returns the value of attribute records.



26
27
28
# File 'lib/dxlite.rb', line 26

def records
  @records
end

#schemaObject (readonly)

Returns the value of attribute schema.



26
27
28
# File 'lib/dxlite.rb', line 26

def schema
  @schema
end

#summaryObject

Returns the value of attribute summary.



25
26
27
# File 'lib/dxlite.rb', line 25

def summary
  @summary
end

Instance Method Details

#allObject



64
65
66
67
68
69
70
71
72
73
# File 'lib/dxlite.rb', line 64

def all()

  @records.map do |h|

    puts 'h: ' + h.inspect if @debug
    RecordX.new(h[:body], self, h[:id], h[:created],
                h[:last_modified])
  end

end

#create(rawh, id: nil, custom_attributes: {created: Time.now.to_s}) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/dxlite.rb', line 85

def create(rawh, id: nil, custom_attributes: {created: Time.now.to_s})

  if @debug then
    puts 'create:: rawh: ' + rawh.inspect
    puts 'custom_attributes: ' + custom_attributes.inspect
  end

  key = @summary[:default_key]

  if key then

    r = records.find {|x| x[:body][key.to_sym] == rawh[key.to_sym]}

    if r then

      # if the client is using create() instead of update() to update a
      # record then update the record
      #
      r[:body].merge!(rawh)
      r[:last_modified] = Time.now.to_s
      save() if @autosave

      return false
    end

  end

  if id.nil? then

    puts '@records: ' + @records.inspect if @debug

    if @records then
      id = @records.map {|x| x[:id].to_i}.max.to_i + 1
    else
      @records = []
      id = 1
    end

  end

  h2 = custom_attributes

  fields = rawh.keys
  puts 'fields: ' + fields.inspect if @debug

  h3 = fields.map {|x| [x.to_sym, nil] }.to_h.merge(rawh)
  h = {id: id.to_s, created: h2[:created], last_modified: nil, body: h3}
  @records << h

  save() if @autosave

  RecordX.new(h[:body], self, h[:id], h[:created], h[:last_modified])

end

#delete(id) ⇒ Object



75
76
77
78
79
80
81
82
83
# File 'lib/dxlite.rb', line 75

def delete(id)
  found = @records.find {|x| x[:id] == id}

  if found then
    @records.delete found
    save() if @autosave
  end

end

#fieldsObject



140
141
142
# File 'lib/dxlite.rb', line 140

def fields()
  @fields
end

#inspectObject



155
156
157
158
# File 'lib/dxlite.rb', line 155

def inspect()
  "#<DxLite:%s @debug=%s, @summary=%s, ...>" % [object_id, @debug,
                                                @summary.inspect]
end

#parse(obj = nil) ⇒ Object Also known as: import

Parses 1 or more lines of text to create or update existing records.



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/dxlite.rb', line 162

def parse(obj=nil)

  @records ||= []

  if obj.is_a? Array then

    unless schema() then
      puts 'obj.first: ' + obj.first.inspect if @debug
      cols = obj.first.keys.map {|c| c == 'id' ? 'uid' : c}
      puts 'after cols' if @debug
      new_summary "items/item(%s)" % cols.join(', ')
    end

    obj.each do |x|
      #puts 'x: ' + x.inspect if @debug
      self.create x, id: nil
    end

    return self

  end
end

#parse_xml(buffer) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/dxlite.rb', line 187

def parse_xml(buffer)

  doc = Rexle.new(buffer.force_encoding('UTF-8'))

  asummary = doc.root.xpath('summary/*').map do |node|
    puts 'node: '  + node.xml.inspect if @debug
    [node.name, node.text.to_s]
  end

  summary = Hash[asummary]
  summary[:schema] = summary['schema']
  %w(recordx_type format_mask schema).each {|x| summary.delete x}

  @schema = summary[:schema]
  puts 'schema: ' + schema.inspect if @debug

  @fields = @schema[/\(([^\)]+)/,1].split(/ *, */)
  puts 'fields: ' + @fields.inspect if @debug

  @summary = summary

  a = doc.root.xpath('records/*').each do |node|

    h = Hash[@fields.map {|field| [field.to_sym, node.text(field).to_s] }]
    self.create h, id: nil, custom_attributes: node.attributes

  end

end

#record(id) ⇒ Object Also known as: find, find_by_id



144
145
146
147
148
149
150
# File 'lib/dxlite.rb', line 144

def record(id)

  h = @records.find {|x| x[:id] == id }
  return unless h
  RecordX.new(h[:body], self, h[:id], h[:created], h[:last_modified])

end

#save(file = @filepath) ⇒ Object



217
218
219
220
221
222
223
224
# File 'lib/dxlite.rb', line 217

def save(file=@filepath)

  return unless file
  @filepath = file

  s = File.extname(file) == '.json' ? to_json() : to_xml()
  FileX.write file, s
end

#to_aObject



226
227
228
# File 'lib/dxlite.rb', line 226

def to_a()
  @records.map {|x| x[:body]}
end

#to_hObject



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/dxlite.rb', line 230

def to_h()

  root_name = schema()[/^\w+/]
  record_name = schema()[/(?<=\/)[^\(]+/]

  records = @records.map {|h| {record_name.to_sym => h} }

  a = if @summary[:order] == 'descending' then

    records.sort_by do |x|

      if @debug then
        puts 'x: ' + x.inspect
        puts 'created: ' + Date.parse(x[:post][:created]).inspect
      end

      created = DateTime.parse(x[:post][:created])

      last_modified = if x[:post][:last_modified] then
        DateTime.parse(x[:post][:last_modified])
      else
        nil
      end

      last_modified || created

    end.reverse

  else

    records

  end

  h = {
    root_name.to_sym =>
    {
      summary: @summary,
      records: a
    }
  }

end

#to_json(pretty: true) ⇒ Object



274
275
276
# File 'lib/dxlite.rb', line 274

def to_json(pretty: true)
  pretty ? JSON.pretty_generate(to_h()) : to_h()
end

#to_xmlObject



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/dxlite.rb', line 278

def to_xml()

  root_name = schema()[/^\w+/]
  record_name = schema()[/(?<=\/)[^\(]+/]

  a = RexleBuilder.build  do |xml|

    xml.send(root_name.to_sym) do
      xml.summary({}, @summary)
      xml.records do

        all().each do |x|

          h = {id: x.id, created: x.created, last_modified: x.last_modified}
          puts 'x.to_h: ' + x.to_h.inspect if @debug
          xml.send(record_name.to_sym, h, x.to_h)

        end

      end
    end
  end

  Rexle.new(a).xml pretty: true


end

#update(id, obj) ⇒ Object

Updates a record from an id and a hash containing field name and field value.

dynarex.update 4, name: Jeff, age: 38


309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/dxlite.rb', line 309

def update(id, obj)

  if @debug then
    puts 'inside update'.info
    puts ('id: ' + id.inspect).debug
    puts ('obj.class: '  + obj.class.inspect).debug
  end

  r = @records.find {|x| x[:id] == id}

  if r then

    r[:body].merge!(obj)
    r[:last_modified] = Time.now.to_s
    save() if @autosave

  end

end