Module: EventStoreRuby::Postgres::Transform

Defined in:
lib/eventstore_ruby/postgres/transform.rb

Class Method Summary collapse

Class Method Details

.deep_snake_symbolize(obj) ⇒ Object

Recursively convert hash keys from camelCase / PascalCase strings to snake_case symbols



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/eventstore_ruby/postgres/transform.rb', line 20

def deep_snake_symbolize(obj)
  case obj
  when Array
    obj.map { |v| deep_snake_symbolize(v) }
  when Hash
    obj.each_with_object({}) do |(k, v), h|
      snake = k.to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
      h[snake] = deep_snake_symbolize(v)
    end
  else
    obj
  end
end

.deserialize_event(row) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# File 'lib/eventstore_ruby/postgres/transform.rb', line 8

def deserialize_event(row)
  raw_payload = row['payload'].is_a?(String) ? JSON.parse(row['payload']) : row['payload']
  normalized = deep_snake_symbolize(raw_payload)
  EventRecord.new(
    sequence_number: row['sequence_number'].to_i,
    timestamp: row['occurred_at'],
    event_type: row['event_type'],
    payload: normalized
  )
end

.extract_max_sequence_number(result) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/eventstore_ruby/postgres/transform.rb', line 38

def extract_max_sequence_number(result)
  return 0 if result.nil?

  if result.respond_to?(:ntuples)
    return 0 if result.ntuples.zero?
    last_row = result[result.ntuples - 1]
    return last_row['sequence_number'].to_i
  elsif result.is_a?(Array)
    return 0 if result.empty?
    return result.last['sequence_number'].to_i
  else
    0
  end
end

.map_records_to_events(result) ⇒ Object



34
35
36
# File 'lib/eventstore_ruby/postgres/transform.rb', line 34

def map_records_to_events(result)
  result.map { |row| deserialize_event(row) }
end

.prepare_insert_params(events, context_params) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/eventstore_ruby/postgres/transform.rb', line 53

def prepare_insert_params(events, context_params)
  event_types_arr = []
  payload_strings = []
  events.each do |event|
    event_types_arr << event.event_type
    payload_strings << event.payload.to_json
  end

  evtypes_literal = '{' + event_types_arr.map { |s| s.gsub('"', '""') }.join(',') + '}'
  payload_literal = '{' + payload_strings.map { |j| '"' + j.gsub('"','\"').gsub('\\','\\\\') + '"' }.join(',') + '}'
  context_params + [evtypes_literal, payload_literal]
end