Skip to content

Instantly share code, notes, and snippets.

@sbellware
Created November 15, 2016 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbellware/fce514231df8d4462c86a75fc622ee4e to your computer and use it in GitHub Desktop.
Save sbellware/fce514231df8d4462c86a75fc622ee4e to your computer and use it in GitHub Desktop.
module Events
class Opened
include Messaging::Message
attribute :account_id, String
attribute :customer_id, String
attribute :time, String
end
class Deposited
include Messaging::Message
attribute :amount, Numeric
attribute :time, String
end
class Withdrawn
include Messaging::Message
attribute :amount, Numeric
attribute :time, String
end
end
class Account
include Schema::DataStructure
attribute :id, String
attribute :customer_id, String
attribute :balance, Numeric, default: 0
attribute :opened_time, Time
attribute :last_transaction_time, Time
def deposit(amount)
self.balance += amount
end
def withdraw(amount)
self.balance -= amount
end
end
class Projection
include EntityProjection
include Events
entity_name :account
apply Opened do |opened|
account.id = opened.account_id
account.customer_id = opened.customer_id
account.opened_time = Time.parse(opened.time)
end
apply Deposited do |deposited|
account.deposit(deposited.amount)
account.last_transaction_time = Time.parse(deposited.time)
end
apply Withdrawn do |withdrawn|
account.withdraw(withdrawn.amount)
account.last_transaction_time = Time.parse(withdrawn.time)
end
end
opened = Events::Opened.build({
customer_id: Identifier::UUID::Random.get,
time: Clock::UTC.iso8601
})
deposited = Events::Deposited.build({
amount: 11,
time: Clock::UTC.iso8601
})
withdrawn = Events::Withdrawn.build({
amount: 1,
time: Clock::UTC.iso8601
})
account_id = Identifier::UUID::Random.get
stream_name = Messaging::StreamName.stream_name(account_id, 'account')
batch = [opened, deposited, withdrawn]
Messaging::Postgres::Write.(batch, stream_name)
account = Account.new
EventSource::Postgres::Read.(stream_name) do |event_data|
Projection.(account, event_data)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment