From cb8768e583f1fb448db67d13591bfdc2def6aed3 Mon Sep 17 00:00:00 2001 From: Kjetil Kjernsmo Date: Sun, 24 Feb 2019 18:04:40 +0100 Subject: [PATCH 1/5] Add transaction role --- lib/Attean/API/Store.pm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Attean/API/Store.pm b/lib/Attean/API/Store.pm index 3048ffca..15fbdc5a 100644 --- a/lib/Attean/API/Store.pm +++ b/lib/Attean/API/Store.pm @@ -219,6 +219,13 @@ package Attean::API::BulkUpdatableStore 0.021 { requires 'end_bulk_updates'; } +package Attean::API::TransactionalStore 0.021 { + use Moo::Role; + + requires 'begin_transaction'; + requires 'end_transaction'; +} + 1; __END__ From cd05bc5944c7a339002d9a07368728cdeedffdc8 Mon Sep 17 00:00:00 2001 From: Kjetil Kjernsmo Date: Mon, 25 Feb 2019 01:08:27 +0100 Subject: [PATCH 2/5] Sequential test --- .../Attean/MutableTransactionalQuadStore.pm | 47 +++++++++++++++++++ t/store-transaction.t | 18 +++++++ 2 files changed, 65 insertions(+) create mode 100644 lib/Test/Attean/MutableTransactionalQuadStore.pm create mode 100644 t/store-transaction.t diff --git a/lib/Test/Attean/MutableTransactionalQuadStore.pm b/lib/Test/Attean/MutableTransactionalQuadStore.pm new file mode 100644 index 00000000..a51dd900 --- /dev/null +++ b/lib/Test/Attean/MutableTransactionalQuadStore.pm @@ -0,0 +1,47 @@ +package Test::Attean::MutableTransactionalQuadStore; + +use v5.14; +use warnings; +use Test::Roo::Role; +use Attean; +use Attean::RDF; +use Proc::Fork; +use Test::Modern; + + +requires 'create_store'; # create_store( quads => \@quads ) +with 'Test::Attean::StoreCleanup'; + +test 'mutabletransactionalquadstore lost update' => sub { + my $self = shift; + my $q1 = quad(iri('s'), iri('p'), dtliteral('35', iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + my $store = $self->create_store(quads => [$q1]); + my $model = Attean::MutableQuadModel->new(store => $store); + my $objects = $model->objects(iri('s'), iri('p'), iri('g')); + does_ok($objects, 'Attean::API::Iterator'); + my $count1 = $objects->next->value; + is($count1, 35, 'Correct initial count'); + $model->remove_quad($q1); + is($model->size, 0); + my $cout1 = $count1 + 100; + my $q2 = quad(iri('s'), iri('p'), dtliteral($cout1, iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + $model->add_quad($q2); + is($model->size, 1); + + # Now next to come around + my $object = $model->objects(iri('s'), iri('p'), iri('g'))->next; + does_ok($object, 'Attean::API::Term'); + my $count2 = $object->value; + is($count2, $cout1, 'Correct count read back'); + my $cout2 = $cout1 - 30; + $model->remove_quad($q2); + my $q3 = quad(iri('s'), iri('p'), dtliteral($cout2, iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + $model->add_quad($q3); + is($model->size, 1); + is($model->objects(iri('s'), iri('p'), iri('g'))->next->value, $cout2, 'Correct count read back'); + + + $self->cleanup_store($store); +}; + +1; diff --git a/t/store-transaction.t b/t/store-transaction.t new file mode 100644 index 00000000..008fd023 --- /dev/null +++ b/t/store-transaction.t @@ -0,0 +1,18 @@ +use Test::Modern; +use Test::Roo; +use Attean; + +use v5.14; + +sub create_store { + my $self = shift; + my %args = @_; + my $store = Attean->get_store('Memory')->new(); + $store->add_quad($args{quads}[0]); + return $store; +} + +with 'Test::Attean::MutableTransactionalQuadStore'; + +run_me; +done_testing; From f405733080a134a7e574d34198a4cbe67e25a11c Mon Sep 17 00:00:00 2001 From: Kjetil Kjernsmo Date: Mon, 25 Feb 2019 01:09:42 +0100 Subject: [PATCH 3/5] Sequential test, note it is --- lib/Test/Attean/MutableTransactionalQuadStore.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Test/Attean/MutableTransactionalQuadStore.pm b/lib/Test/Attean/MutableTransactionalQuadStore.pm index a51dd900..39ced5f4 100644 --- a/lib/Test/Attean/MutableTransactionalQuadStore.pm +++ b/lib/Test/Attean/MutableTransactionalQuadStore.pm @@ -12,7 +12,7 @@ use Test::Modern; requires 'create_store'; # create_store( quads => \@quads ) with 'Test::Attean::StoreCleanup'; -test 'mutabletransactionalquadstore lost update' => sub { +test 'mutabletransactionalquadstore sequential' => sub { my $self = shift; my $q1 = quad(iri('s'), iri('p'), dtliteral('35', iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); my $store = $self->create_store(quads => [$q1]); From 459b3867863a91f43e62edcdab8a34dd61edec62 Mon Sep 17 00:00:00 2001 From: Kjetil Kjernsmo Date: Mon, 25 Feb 2019 01:23:42 +0100 Subject: [PATCH 4/5] Failing tests without transactions --- .../Attean/MutableTransactionalQuadStore.pm | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lib/Test/Attean/MutableTransactionalQuadStore.pm b/lib/Test/Attean/MutableTransactionalQuadStore.pm index 39ced5f4..24e65de1 100644 --- a/lib/Test/Attean/MutableTransactionalQuadStore.pm +++ b/lib/Test/Attean/MutableTransactionalQuadStore.pm @@ -44,4 +44,44 @@ test 'mutabletransactionalquadstore sequential' => sub { $self->cleanup_store($store); }; + +test 'mutabletransactionalquadstore lost update' => sub { + my $self = shift; + my $q1 = quad(iri('s'), iri('p'), dtliteral('35', iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + my $store = $self->create_store(quads => [$q1]); + my $model = Attean::MutableQuadModel->new(store => $store); + + run_fork { + child { + my $objects = $model->objects(iri('s'), iri('p'), iri('g')); + does_ok($objects, 'Attean::API::Iterator'); + my $count1 = $objects->next->value; + is($count1, 35, 'Correct initial count'); + $model->remove_quad($q1); + is($model->size, 0); + my $cout1 = $count1 + 100; + my $q2 = quad(iri('s'), iri('p'), dtliteral($cout1, iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + $model->add_quad($q2); + is($model->size, 1); + }; + child { + # Now next to come around + my $object = $model->objects(iri('s'), iri('p'), iri('g'))->next; + does_ok($object, 'Attean::API::Term'); + my $count2 = $object->value; + my $cout1 = 135; + is($count2, $cout1, 'Correct count read back'); + my $cout2 = $cout1 - 30; + my $q2 = quad(iri('s'), iri('p'), dtliteral($cout1, iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + $model->remove_quad($q2); + my $q3 = quad(iri('s'), iri('p'), dtliteral($cout2, iri('http://www.w3.org/2001/XMLSchema#integer')), iri('g')); + $model->add_quad($q3); + is($model->size, 1); + is($model->objects(iri('s'), iri('p'), iri('g'))->next->value, $cout2, 'Correct count read back'); + } + }; + + $self->cleanup_store($store); +}; + 1; From ac8cb2ed658bf01561227802b5fecade4c7466ff Mon Sep 17 00:00:00 2001 From: Kjetil Kjernsmo Date: Mon, 25 Feb 2019 01:33:32 +0100 Subject: [PATCH 5/5] Add test_requires --- Makefile.PL | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.PL b/Makefile.PL index ceab9eeb..29514e39 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -15,6 +15,8 @@ test_requires 'Test::Exception' => 0; test_requires 'Test::LWP::UserAgent' => 0; test_requires 'Test::More' => 0.88; test_requires 'XML::Simple' => 0; +test_requires 'Test::Modern' => 0; +test_requires 'Proc::Fork' => 0; perl_version '5.014';