Class: PgLedger::Posting

Inherits:
Object
  • Object
show all
Defined in:
lib/pg_ledger/posting.rb

Constant Summary collapse

CALL_SQL =
<<~SQL
  SELECT * FROM pg_ledger_post(?, ?, ?::jsonb, ?, ?::jsonb, ?::jsonb, ?, ?)
SQL
ERROR_MARKERS =
{
  "pg_ledger:insufficient_balance" => :InsufficientBalance,
  "pg_ledger:idempotency_conflict" => :IdempotencyConflict,
  "pg_ledger:frozen_account" => :FrozenAccount,
  "pg_ledger:period_closed" => :PeriodClosed,
  "pg_ledger:over_reversal" => :OverReversal,
  "pg_ledger:invalid_reversal" => :InvalidReversal,
  "pg_ledger:cross_ledger" => :CrossLedger,
  "is not balanced" => :Unbalanced,
  "rows are immutable" => :ImmutableRecord
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(legs:, idempotency_key:, metadata:, posted_at:, reverses: nil, shard_hint: nil, ledger_id: Ledger::DEFAULT_ID) ⇒ Posting

Returns a new instance of Posting.



9
10
11
12
13
14
15
16
17
18
# File 'lib/pg_ledger/posting.rb', line 9

def initialize(legs:, idempotency_key:, metadata:, posted_at:, reverses: nil,
               shard_hint: nil, ledger_id: Ledger::DEFAULT_ID)
  @legs = legs
  @idempotency_key = idempotency_key
  @metadata =  || {}
  @posted_at = posted_at
  @reverses = reverses
  @shard_hint = shard_hint
  @ledger_id = ledger_id
end

Class Method Details

.map_pg_error(error) ⇒ Object



58
59
60
61
62
63
# File 'lib/pg_ledger/posting.rb', line 58

def self.map_pg_error(error)
  ERROR_MARKERS.each do |marker, name|
    return PgLedger.const_get(name).new(error.message) if error.message.include?(marker)
  end
  error
end

Instance Method Details

#call ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/pg_ledger/posting.rb', line 20

def call
  prepare
  rows = Entry.find_by_sql(
    [CALL_SQL, @idempotency_key, digest, JSON.generate(@metadata), @posted_at,
     JSON.generate(legs_payload), JSON.generate(deltas_payload), @reverses, @ledger_id]
  )
  rows.first
rescue ActiveRecord::StatementInvalid => e
  raise Posting.map_pg_error(e)
end

#payload ⇒ Object

For Batch: everything the SQL function needs, no execution.



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/pg_ledger/posting.rb', line 32

def payload
  prepare
  {
    idempotency_key: @idempotency_key,
    request_digest: digest,
    metadata: @metadata,
    posted_at: @posted_at,
    reverses_entry_id: @reverses,
    ledger_id: @ledger_id,
    legs: legs_payload,
    deltas: deltas_payload
  }
end