File Coverage

blib/lib/Test/AtteanX/Store/DBI.pm
Criterion Covered Total %
statement 35 35 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod 0 1 0.0
total 44 45 97.7


line stmt bran cond sub pod time code
1             package Test::AtteanX::Store::DBI;
2              
3 1     1   42797 use utf8;
  1         3  
  1         14  
4 1     1   46 use v5.14;
  1         4  
5 1     1   5 use warnings;
  1         9  
  1         31  
6 1     1   6 use Test::Roo::Role;
  1         2  
  1         17  
7 1     1   3282 use Test::Modern;
  1         7  
  1         9  
8 1     1   4861 use Test::Moose;
  1         4  
  1         6  
9 1     1   614 use Attean;
  1         9  
  1         6  
10 1     1   24 use Attean::RDF;
  1         12  
  1         6  
11              
12             requires 'create_store'; # create_store( quads => \@triples )
13              
14             sub test_quads {
15 7     7 0 17825 my @q;
16 7         30 for my $i (0 .. 5) {
17 42         46022 push(@q, quad(iri('s'), iri('p'), literal($i), iri('g')));
18 42         99847 push(@q, quad(iri('s'), iri('p'), blank("b$i"), iri('g')));
19             }
20              
21 7         8432 my @strings;
22 7         31 push(@strings, literal('Hi'));
23 7         6936 push(@strings, langliteral('Hello', 'en'));
24 7         7504 push(@strings, langliteral('火星', 'ja'));
25 7         7230 push(@strings, dtliteral(787, 'http://www.w3.org/2001/XMLSchema#integer'));
26 7         11051 foreach my $s (@strings) {
27 28         23598 push(@q, quad(iri('s'), iri('str'), $s, iri('strings')));
28             }
29              
30 7         7892 return \@q;
31             }
32              
33             test 'ISLITERAL type constraint SARG' => sub {
34             my $self = shift;
35             my $store = $self->create_store(quads => $self->test_quads);
36             my $model = Attean::QuadModel->new( store => $store );
37             my $dbh = $store->dbh;
38             my $typecol = $dbh->quote_identifier('type');
39            
40             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER ISLITERAL(?o) }');
41             my $default_graphs = [iri('g')];
42             my $planner = Attean::IDPQueryPlanner->new();
43             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
44              
45             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
46             my ($sql, @bind) = $plan->sql;
47            
48             like($sql, qr<SELECT term_id FROM term WHERE $typecol = [?]>, 'generated SQL');
49             is($bind[-1], 'literal');
50             };
51              
52             test 'ISBLANK type constraint SARG' => sub {
53             my $self = shift;
54             my $store = $self->create_store(quads => $self->test_quads);
55             my $model = Attean::QuadModel->new( store => $store );
56             my $dbh = $store->dbh;
57             my $typecol = $dbh->quote_identifier('type');
58              
59             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER isBlank(?o) }');
60             my $default_graphs = [iri('g')];
61             my $planner = Attean::IDPQueryPlanner->new();
62             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
63              
64             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
65             my ($sql, @bind) = $plan->sql;
66             like($sql, qr<SELECT term_id FROM term WHERE $typecol = [?]>, 'generated SQL');
67             is($bind[-1], 'blank', 'bound values');
68             };
69              
70             test 'ISLITERAL type constraint SARG' => sub {
71             my $self = shift;
72             my $store = $self->create_store(quads => $self->test_quads);
73             my $model = Attean::QuadModel->new( store => $store );
74             my $dbh = $store->dbh;
75             my $typecol = $dbh->quote_identifier('type');
76              
77             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER ISLITERAL(?o) }');
78             my $default_graphs = [iri('strings')];
79             my $planner = Attean::IDPQueryPlanner->new();
80             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
81              
82             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
83             my ($sql, @bind) = $plan->sql;
84             like($sql, qr<SELECT term_id FROM term WHERE $typecol = [?]>, 'generated SQL');
85             is($bind[-1], 'literal', 'bound values');
86             };
87              
88             test 'ISIRI type constraint SARG' => sub {
89             my $self = shift;
90             my $store = $self->create_store(quads => $self->test_quads);
91             my $model = Attean::QuadModel->new( store => $store );
92             my $dbh = $store->dbh;
93             my $typecol = $dbh->quote_identifier('type');
94              
95             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER ISIRI(?o) }');
96             my $default_graphs = [iri('g')];
97             my $planner = Attean::IDPQueryPlanner->new();
98             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
99              
100             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
101             my ($sql, @bind) = $plan->sql;
102             like($sql, qr<SELECT term_id FROM term WHERE $typecol = [?]>, 'generated SQL');
103             is($bind[-1], 'iri');
104             };
105              
106             test 'STRSTARTS' => sub {
107             my $self = shift;
108             my $store = $self->create_store(quads => $self->test_quads);
109             my $model = Attean::QuadModel->new( store => $store );
110            
111             subtest 'STR()' => sub {
112             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER STRSTARTS(STR(?o), "H") }');
113             my $default_graphs = [iri('strings')];
114             my $planner = Attean::IDPQueryPlanner->new();
115             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
116              
117             my @rows = $plan->evaluate($model)->elements;
118             is(scalar(@rows), 2, 'result count');
119             foreach my $r (@rows) {
120             like($r->value('o')->value, qr/^H/, 'literal value');
121             }
122             };
123            
124             subtest 'xsd:string' => sub {
125             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER STRSTARTS(?o, "H") }');
126             my $default_graphs = [iri('strings')];
127             my $planner = Attean::IDPQueryPlanner->new();
128             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
129              
130             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
131             my $iter = $plan->evaluate($model);
132             my @rows = $iter->elements;
133             is(scalar(@rows), 2, 'result count');
134             foreach my $r (@rows) {
135             like($r->value('o')->value, qr/^H/, 'literal value');
136             }
137             };
138            
139             subtest 'language string' => sub {
140             my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ?s ?p ?o FILTER STRSTARTS(?o, "H"@en) }');
141             my $default_graphs = [iri('strings')];
142             my $planner = Attean::IDPQueryPlanner->new();
143             my $plan = $planner->plan_for_algebra($algebra, $model, $default_graphs);
144              
145             isa_ok($plan, 'AtteanX::Store::DBI::Plan');
146             my @rows = $plan->evaluate($model)->elements;
147             is(scalar(@rows), 1, 'result count');
148             is($rows[0]->value('o')->value, 'Hello', 'literal value');
149             };
150             };
151              
152              
153             1;