Skip to content

Commit

Permalink
Merge branch 'registry_review' (closes #25)
Browse files Browse the repository at this point in the history
  • Loading branch information
memowe committed Nov 25, 2018
2 parents f525877 + d7444a2 commit 04b8184
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 187 deletions.
2 changes: 1 addition & 1 deletion Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
0.6 ????-??-??
- BREAKING CHANGE: Serialization API has changed and uses YAML instead of Storable
- Use a transformation store build on startup time instead of serializing subroutines
- Transparent refactoring of internal event registration and handling

0.51 2018-08-24
- No relevant changes, but a version bump was neccessary because I broke my MANIFEST file. Sorry! :-)
Expand Down
36 changes: 12 additions & 24 deletions lib/EventStore/Tiny.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use warnings;

use EventStore::Tiny::Logger;
use EventStore::Tiny::Event;
use EventStore::Tiny::DataEvent;
use EventStore::Tiny::TransformationStore;
use EventStore::Tiny::EventStream;
use EventStore::Tiny::Snapshot;
Expand All @@ -18,7 +17,6 @@ use Data::Compare; # Exports Compare()
our $VERSION = '0.6';

use Class::Tiny {
registry => sub {{}},
events => sub {EventStore::Tiny::EventStream->new(
logger => shift->logger)},
trans_store => sub {EventStore::Tiny::TransformationStore->new},
Expand All @@ -40,7 +38,7 @@ sub import_events {
# Create
my $stream = EventStore::Tiny::EventStream->new;
for my $data (@$events) {
$stream->add_event(EventStore::Tiny::DataEvent->new(
$stream->add_event(EventStore::Tiny::Event->new(
uuid => $data->{uuid},
timestamp => $data->{timestamp},
name => $data->{name},
Expand Down Expand Up @@ -78,29 +76,25 @@ sub register_event {

# Register transformation
$self->trans_store->set($name => $transformation);

return $self->registry->{$name} = EventStore::Tiny::Event->new(
name => $name,
trans_store => $self->trans_store,
logger => $self->logger,
);
}

sub event_names {
my $self = shift;
return [sort keys %{$self->registry}];
return [$self->trans_store->names];
}

sub store_event {
my ($self, $name, $data) = @_;

# Lookup template event
my $template = $self->registry->{$name};
die "Unknown event: $name!\n" unless defined $template;
# Lookup event type
die "Unknown event: $name!\n"
unless defined $self->trans_store->get($name);

# Specialize event with new data
my $event = EventStore::Tiny::DataEvent->new_from_template(
$template, $data
# Create event
my $event = EventStore::Tiny::Event->new(
name => $name,
trans_store => $self->trans_store,
data => $data,
);

# Done
Expand Down Expand Up @@ -344,19 +338,13 @@ Returns a L<EventStore::Tiny::Snapshot> object which basically consists of the c
my $types = $store->event_names;
Returns an arrayref containing all event type names of registered events, sorted by name. These names are the values of L</registry>.
=head3 registry
my $user_added = $store->registry->{UserAdded};
Returns a hashref with event type names as keys and event types as values, which are L<EventStore::Tiny::Event> instances. Should be manipulated by L</register_event> only.
Returns an arrayref containing all event type names of registered events, sorted by name.
=head3 events
my $event_stream = $store->events;
Returns the internal L<EventStore::Tiny::EventStream> object that stores all concrete events (L<EventStore::Tiny::DataEvent> instances). Should be manipulated by L</store_event> only. Events should never be changed or removed.
Returns the internal L<EventStore::Tiny::EventStream> object that stores all concrete events (L<EventStore::Tiny::Event> instances). Should be manipulated by L</store_event> only. Events should never be changed or removed.
=head3 trans_store
Expand Down
109 changes: 0 additions & 109 deletions lib/EventStore/Tiny/DataEvent.pm

This file was deleted.

28 changes: 25 additions & 3 deletions lib/EventStore/Tiny/Event.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use Class::Tiny {
timestamp => sub {time},
name => sub {die "name is required.\n"},
trans_store => sub {die "trans_store is required."},
data => sub {{}},
};

sub BUILD {
Expand Down Expand Up @@ -38,7 +39,7 @@ sub apply_to {
my ($self, $state, $logger) = @_;

# Apply the transformation by side effect
$self->transformation->($state);
$self->transformation->($state, $self->data);

# Log this event, if logger present
$logger->($self) if defined $logger;
Expand All @@ -50,13 +51,29 @@ sub apply_to {
# Return a one-line summary of this event
sub summary {
my $self = shift;

# Prepare date and time
my $decimals = $self->timestamp =~ /(\.\d+)$/ ? $1 : '';
my @time_parts = localtime $self->timestamp;
return sprintf '[%s (%4d-%02d-%02dT%02d:%02d:%02d%s)]',

# Prepare data summary
my $data_summary = join ', ' => map {
my $d = $self->data->{$_};
$d =~ s/\s+/ /g; # Summarize in-between whitespace
$d =~ s/^\s+//; # Get rid of leading whitespace
$d =~ s/\s+$//; # Get rid of whitespace in the end
$d =~ s/['"]+//g; # Get rid of quotes
$d =~ s/^(.{17}).{3,}/$1.../; # Shorten
"$_: '$d'" # Quoted, shortened key-value pair
} sort keys %{$self->data};

# Concatenate
return sprintf '[%s (%4d-%02d-%02dT%02d:%02d:%02d%s)%s]',
$self->name,
$time_parts[5] + 1900, # Year
@time_parts[4, 3, 2, 1, 0], # Rest of time representation
$decimals; # Possibly empty
$decimals, # Possibly empty
($data_summary ne '' ? " | $data_summary" : '');
}

1;
Expand All @@ -80,6 +97,7 @@ All these attributes can be manipulated by setters/getters with the attribute's
my $event = EventStore::Tiny::Event->new(
name => 'Foo',
trans_store => $ts,
data => {id => 42},
);
=head3 uuid
Expand All @@ -98,6 +116,10 @@ This event's name. Setting this attribute on construction is required.
The L<EventStore::Tiny::TransformationStore> object where this event's transformation subroutine will be looked up on application.
=head3 data
Concrete data for this event which will be used during application.
=head2 METHODS
=head3 transformation
Expand Down
2 changes: 1 addition & 1 deletion lib/EventStore/Tiny/Logger.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ sub log_event {

# Stringify
use Data::Dump 'dump';
my $data = $event->can('data') ? dump $event->data : 'NO DATA';
my $data = keys(%{$event->data}) ? dump $event->data : 'NO DATA';
my $output = $event->name . ": $data";

# Print to given print handle
Expand Down
46 changes: 11 additions & 35 deletions t/1_unit/event.t
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use Test::More;
use EventStore::Tiny::TransformationStore;

use_ok 'EventStore::Tiny::Event';
use_ok 'EventStore::Tiny::DataEvent';

subtest 'Defaults' => sub {
subtest 'Construction' => sub {

subtest 'UUID' => sub {

Expand Down Expand Up @@ -58,6 +57,14 @@ subtest 'Defaults' => sub {
'Transformation store is required';
};

subtest 'Data' => sub {
my $e = EventStore::Tiny::Event->new(
name => 'foo',
trans_store => EventStore::Tiny::TransformationStore->new,
);
is_deeply $e->data => {}, 'Empty default data hash';
};

subtest 'Summary' => sub {
my $e = EventStore::Tiny::Event->new(
name => 'foo',
Expand Down Expand Up @@ -128,7 +135,7 @@ subtest 'Application' => sub {
};
};

subtest 'Data event' => sub {
subtest 'Event with data' => sub {

# Prepare
my $ts = EventStore::Tiny::TransformationStore->new;
Expand All @@ -137,16 +144,8 @@ subtest 'Data event' => sub {
$state->{$data->{key}} = 42;
});

subtest 'Default data' => sub {
my $e = EventStore::Tiny::DataEvent->new(
name => 'foo',
trans_store => $ts,
);
is_deeply $e->data => {}, 'Default data is an empty hash';
};

# Construct data-driven event
my $ev = EventStore::Tiny::DataEvent->new(
my $ev = EventStore::Tiny::Event->new(
name => 'foo',
trans_store => $ts,
data => {key => 'quux'},
Expand Down Expand Up @@ -192,27 +191,4 @@ subtest 'Data event' => sub {
};
};

subtest 'Specialization' => sub {

# Construct data-driven event
my $ts = EventStore::Tiny::TransformationStore->new;
$ts->set(foo => sub {
my ($state, $data) = @_;
$state->{$data->{key}} = 42;
});
my $ev = EventStore::Tiny::Event->new(
name => 'foo',
trans_store => $ts,
);

# Specialize
my $de = EventStore::Tiny::DataEvent->new_from_template(
$ev, {key => 'quux'}
);
isa_ok $de => 'EventStore::Tiny::Event';

# Apply to empty state
is $de->apply_to({})->{quux} => 42, 'Correct state-update from new data';
};

done_testing;

0 comments on commit 04b8184

Please sign in to comment.