Class: Pgoutput::Decoder::RowBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/pgoutput/decoder/row_builder.rb,
sig/pgoutput_decoder.rbs

Overview

Builds decoded row hashes from Relation metadata and TupleValue arrays.

Instance Method Summary collapse

Constructor Details

#initialize(type_registry: TypeRegistry.default) ⇒ RowBuilder

Returns a new instance of RowBuilder.

Parameters:

  • type_registry (TypeRegistry) (defaults to: TypeRegistry.default)
  • type_registry: (TypeRegistry) (defaults to: TypeRegistry.default)


11
12
13
14
# File 'lib/pgoutput/decoder/row_builder.rb', line 11

def initialize(type_registry: TypeRegistry.default)
  @value_decoder = ValueDecoder.new(type_registry: type_registry)
  freeze
end

Instance Method Details

#build(relation, tuple) ⇒ Hash<String, Object>

Build a decoded row hash.

Parameters:

  • relation (Pgoutput::Messages::Relation)
  • tuple (Array<Pgoutput::Messages::TupleValue>)

Returns:

  • (Hash<String, Object>)


21
22
23
# File 'lib/pgoutput/decoder/row_builder.rb', line 21

def build(relation, tuple)
  build_columns(relation.columns, tuple)
end

#build_columns(columns, tuple, key_only: false) ⇒ Hash[String, untyped]

Parameters:

  • columns (Array[untyped])
  • tuple (tuple)
  • key_only: (Boolean) (defaults to: false)

Returns:

  • (Hash[String, untyped])


43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/pgoutput/decoder/row_builder.rb', line 43

def build_columns(columns, tuple, key_only: false)
  row = {} # : Hash[String, untyped]

  tuple.each_with_index do |tuple_value, index|
    column = columns[index]
    next unless column
    next if key_only && !key_column?(column)

    normalized_value = normalize_oid(tuple_value, column.oid)
    row[column.name] = @value_decoder.decode(normalized_value)
  end

  Ractor.make_shareable(row.freeze)
end

#build_key(relation, tuple) ⇒ Hash<String, Object>

Build a decoded replica-key hash.

PostgreSQL may encode an old-key tuple at full relation width with placeholders for non-key columns, while compact protocol fixtures may contain only key values. Relation flags determine the exact key columns in both representations.

Parameters:

  • relation (Pgoutput::Messages::Relation)
  • tuple (Array<Pgoutput::Messages::TupleValue>)

Returns:

  • (Hash<String, Object>)


35
36
37
38
39
# File 'lib/pgoutput/decoder/row_builder.rb', line 35

def build_key(relation, tuple)
  key_columns = relation.columns.select { |column| key_column?(column) }
  columns = tuple.length == relation.columns.length ? relation.columns : key_columns
  build_columns(columns, tuple, key_only: true)
end

#key_column?(column) ⇒ Boolean

Parameters:

  • column (Object)

Returns:

  • (Boolean)


58
59
60
# File 'lib/pgoutput/decoder/row_builder.rb', line 58

def key_column?(column)
  column.flags.allbits?(1)
end

#normalize_oid(tuple_value, oid) ⇒ Object

Parameters:

  • tuple_value (Object)
  • oid (Integer)

Returns:

  • (Object)


62
63
64
65
66
# File 'lib/pgoutput/decoder/row_builder.rb', line 62

def normalize_oid(tuple_value, oid)
  return tuple_value unless tuple_value.oid.nil?

  Pgoutput::Messages::TupleValue.new(tuple_value.format, tuple_value.raw, oid)
end