Class: StructuredDataToSql::Json::RecordStreamer::Handler

Inherits:
Oj::ScHandler
  • Object
show all
Defined in:
lib/structured_data_to_sql/json/record_streamer.rb

Overview

-- Oj::ScHandler callback names

Constant Summary collapse

RECORDS =
Object.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(records_key:, on_record:, records_path: nil) ⇒ Handler

records_key is the single-key fallback used to match a depth-1 array (kept for legacy single-key paths and the default "data" case). records_path is the full key sequence for multi-level paths; when set, the handler descends through intermediate objects until the final segment matches an array — that array becomes the RECORDS stream.



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 307

def initialize(records_key:, on_record:, records_path: nil)
  super()
  @records_key = records_key
  @records_path = records_path
  @on_record = on_record
  @stack = []
  @pending_key = nil
  @envelope = nil
  @records_found = false
  @records_key_used = nil
  @record_count = 0
  @root_value = nil
  # Number of path segments matched by the current object branch.
  @path_matched = 0
  @path_match_stack = []
  # The most recent key seen at the current path match depth.
  @path_pending_key = nil
end

Instance Attribute Details

#envelopeObject (readonly)

Returns the value of attribute envelope.



300
301
302
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 300

def envelope
  @envelope
end

#record_countObject (readonly)

Returns the value of attribute record_count.



300
301
302
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 300

def record_count
  @record_count
end

#records_key_usedObject (readonly)

Returns the value of attribute records_key_used.



300
301
302
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 300

def records_key_used
  @records_key_used
end

#root_valueObject (readonly)

Returns the value of attribute root_value.



300
301
302
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 300

def root_value
  @root_value
end

Instance Method Details

#add_value(value) ⇒ Object



397
398
399
400
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 397

def add_value(value)
  @root_value = value
  @envelope = {} if @envelope.nil?
end

#array_append(array, value) ⇒ Object



388
389
390
391
392
393
394
395
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 388

def array_append(array, value)
  if array.equal?(RECORDS)
    @on_record.call(value, @record_count)
    @record_count += 1
  else
    array << value
  end
end

#array_endObject



384
385
386
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 384

def array_end
  @stack.pop
end

#array_startObject



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 363

def array_start
  target =
    if @stack.empty?
      @records_found = true
      RECORDS
    elsif multi_level_records_array?
      @records_found = true
      @records_key_used = @records_path.join(".")
      RECORDS
    elsif @stack.length == 1 && @stack.first.equal?(@envelope) &&
          @pending_key == @records_key
      @records_found = true
      @records_key_used = @records_key
      RECORDS
    else
      []
    end
  @stack.push(target)
  target
end

#hash_endObject



340
341
342
343
344
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 340

def hash_end
  obj = @stack.pop
  @path_matched = @path_match_stack.pop || 0
  obj
end

#hash_key(key) ⇒ Object



346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 346

def hash_key(key)
  # Legacy single-level match: track the pending key at depth 1.
  @pending_key = key if @stack.length == 1

  # Multi-level path: track the key seen at the current match depth,
  # and advance the match counter for non-final segments.
  if @records_path && !@records_found
    @path_pending_key = key if @stack.length == @path_matched + 1
  end

  key
end

#hash_set(hash, key, value) ⇒ Object



359
360
361
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 359

def hash_set(hash, key, value)
  hash[key] = value unless value.equal?(RECORDS)
end

#hash_startObject



330
331
332
333
334
335
336
337
338
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 330

def hash_start
  hash = {}
  previous_path_matched = @path_matched
  @path_matched += 1 if path_intermediate_value?
  @path_match_stack.push(previous_path_matched)
  @envelope = hash if @stack.empty?
  @stack.push(hash)
  hash
end

#records_foundObject



326
327
328
# File 'lib/structured_data_to_sql/json/record_streamer.rb', line 326

def records_found
  @records_found
end