Passed
Push — extract-store ( f24e42...0c7df1 )
by Konrad
04:35
created

SelectQueryTest::testSelectOrderByAsc()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 23
nc 1
nop 0
dl 0
loc 47
rs 9.552
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the sweetrdf/InMemoryStoreSqlite package and licensed under
5
 * the terms of the GPL-3 license.
6
 *
7
 * (c) Konrad Abicht <[email protected]>
8
 * (c) Benjamin Nowack
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Tests\Integration\Store\InMemoryStoreSqlite\Query;
15
16
use sweetrdf\InMemoryStoreSqlite\Logger;
17
use sweetrdf\InMemoryStoreSqlite\PDOSQLiteAdapter;
18
use sweetrdf\InMemoryStoreSqlite\Store\InMemoryStoreSqlite;
19
use Tests\TestCase;
20
21
/**
22
 * Tests for query method - focus on SELECT queries.
23
 */
24
class SelectQueryTest extends TestCase
25
{
26
    protected function setUp(): void
27
    {
28
        parent::setUp();
29
30
        $this->subjectUnderTest = new InMemoryStoreSqlite(new PDOSQLiteAdapter(), new Logger());
31
    }
32
33
    public function testSelectDefaultGraph()
34
    {
35
        // test data
36
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
37
            <http://s> <http://p1> "baz" .
38
        }');
39
40
        $res = $this->subjectUnderTest->query('SELECT * WHERE {<http://s> <http://p1> ?o.}');
41
        $this->assertEquals(
42
            [
43
                'query_type' => 'select',
44
                'result' => [
45
                    'variables' => [
46
                        'o',
47
                    ],
48
                    'rows' => [
49
                        [
50
                            'o' => 'baz',
51
                            'o type' => 'literal',
52
                        ],
53
                    ],
54
                ],
55
                'query_time' => $res['query_time'],
56
            ],
57
            $res
58
        );
59
    }
60
61
    public function testSelectGraphSpecified()
62
    {
63
        // test data
64
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
65
            <http://s> <http://p1> "baz" .
66
        }');
67
68
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://example.com/> WHERE {<http://s> <http://p1> ?o.}');
69
        $this->assertEquals(
70
            [
71
                'query_type' => 'select',
72
                'result' => [
73
                    'variables' => [
74
                        'o',
75
                    ],
76
                    'rows' => [
77
                        [
78
                            'o' => 'baz',
79
                            'o type' => 'literal',
80
                        ],
81
                    ],
82
                ],
83
                'query_time' => $res['query_time'],
84
            ],
85
            $res
86
        );
87
    }
88
89
    // simulate a LEFT JOIN using OPTIONAL
90
    public function testSelectLeftJoinUsingOptional()
91
    {
92
        // test data
93
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
94
            <http://a> <http://p1> <http://b> .
95
            <http://a> <http://p1> <http://c> .
96
97
            <http://b> <http://p1> <http://d> .
98
            <http://b> <http://p1> <http://e> .
99
100
            <http://c> <http://p1> <http://f> .
101
        }');
102
103
        $res = $this->subjectUnderTest->query('
104
            SELECT * WHERE {
105
                ?s <http://p1> ?o .
106
                OPTIONAL {
107
                    ?o <http://p1> ?o2 .
108
                }
109
            }
110
        ');
111
        $this->assertEquals(
112
            [
113
                [
114
                    's' => 'http://a',
115
                    's type' => 'uri',
116
                    'o' => 'http://b',
117
                    'o type' => 'uri',
118
                ],
119
                [
120
                    's' => 'http://a',
121
                    's type' => 'uri',
122
                    'o' => 'http://c',
123
                    'o type' => 'uri',
124
                ],
125
                [
126
                    's' => 'http://b',
127
                    's type' => 'uri',
128
                    'o' => 'http://d',
129
                    'o type' => 'uri',
130
                ],
131
                [
132
                    's' => 'http://b',
133
                    's type' => 'uri',
134
                    'o' => 'http://e',
135
                    'o type' => 'uri',
136
                ],
137
                [
138
                    's' => 'http://c',
139
                    's type' => 'uri',
140
                    'o' => 'http://f',
141
                    'o type' => 'uri',
142
                ],
143
            ],
144
            $res['result']['rows']
145
        );
146
    }
147
148
    /*
149
     * OPTIONAL, artifical query to extend coverage for store code. (SelectQueryHandler::sameOptional)
150
     */
151
    public function testSelectOptional()
152
    {
153
        // test data
154
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
155
            <http://s1> <http://p1> <http://s2> .
156
        }');
157
158
        $res = $this->subjectUnderTest->query('
159
            SELECT * WHERE {
160
                ?s <http://p1> ?o .
161
                OPTIONAL {
162
                    ?o <http://p1> ?o2 .
163
                }
164
                OPTIONAL {
165
                    ?o <http://p1> ?o2 .
166
                }
167
            }
168
        ');
169
        $this->assertEquals(
170
            [
171
                'query_type' => 'select',
172
                'result' => [
173
                    'variables' => [
174
                        's', 'o', 'o2',
175
                    ],
176
                    'rows' => [
177
                        [
178
                            's' => 'http://s1',
179
                            's type' => 'uri',
180
                            'o' => 'http://s2',
181
                            'o type' => 'uri',
182
                        ],
183
                    ],
184
                ],
185
                'query_time' => $res['query_time'],
186
            ],
187
            $res
188
        );
189
    }
190
191
    public function testSelectNoWhereClause()
192
    {
193
        // test data
194
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
195
            <http://s> <http://p1> "baz" .
196
        }');
197
198
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://example.com/> {<http://s> <http://p1> ?o.}');
199
        $this->assertEquals(
200
            [
201
                'query_type' => 'select',
202
                'result' => [
203
                    'variables' => [
204
                        'o',
205
                    ],
206
                    'rows' => [
207
                        [
208
                            'o' => 'baz',
209
                            'o type' => 'literal',
210
                        ],
211
                    ],
212
                ],
213
                'query_time' => $res['query_time'],
214
            ],
215
            $res
216
        );
217
    }
218
219
    /*
220
     * FILTER
221
     */
222
223
    // bound: is variable set?
224
    public function testSelectFilterBoundNotBounding()
225
    {
226
        // test data
227
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
228
            <http://s> <http://p1> "foo" .
229
        }');
230
231
        $res = $this->subjectUnderTest->query('
232
            SELECT ?s ?o WHERE {
233
                ?s <http://p2> ?o .
234
                FILTER (bound(?o))
235
            }
236
        ');
237
        $this->assertEquals(
238
            [
239
                'query_type' => 'select',
240
                'result' => [
241
                    'variables' => [
242
                        's', 'o',
243
                    ],
244
                    'rows' => [],
245
                ],
246
                'query_time' => $res['query_time'],
247
            ],
248
            $res
249
        );
250
    }
251
252
    // bound: is variable set?
253
    public function testSelectFilterBoundVariableBounded()
254
    {
255
        // test data
256
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
257
            <http://s> <http://p1> "foo" .
258
        }');
259
260
        $res = $this->subjectUnderTest->query('
261
            SELECT ?s ?o WHERE {
262
                ?s <http://p1> ?o .
263
                FILTER (bound(?o))
264
            }
265
        ');
266
        $this->assertEquals(
267
            [
268
                'query_type' => 'select',
269
                'result' => [
270
                    'variables' => [
271
                        's', 'o',
272
                    ],
273
                    'rows' => [
274
                        [
275
                            's' => 'http://s',
276
                            's type' => 'uri',
277
                            'o' => 'foo',
278
                            'o type' => 'literal',
279
                        ],
280
                    ],
281
                ],
282
                'query_time' => $res['query_time'],
283
            ],
284
            $res
285
        );
286
    }
287
288
    // datatype
289
    public function testSelectFilterDatatype()
290
    {
291
        // test data
292
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
293
            <http://s> <http://p1> 3 .
294
        }');
295
296
        $res = $this->subjectUnderTest->query('
297
            SELECT ?s ?o WHERE {
298
                ?s <http://p1> ?o .
299
                FILTER (datatype(?o) = xsd:integer)
300
            }
301
        ');
302
        $this->assertEquals(
303
            [
304
                'query_type' => 'select',
305
                'result' => [
306
                    'variables' => [
307
                        's', 'o',
308
                    ],
309
                    'rows' => [
310
                        [
311
                            's' => 'http://s',
312
                            's type' => 'uri',
313
                            'o' => '3',
314
                            'o type' => 'literal',
315
                            'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
316
                        ],
317
                    ],
318
                ],
319
                'query_time' => $res['query_time'],
320
            ],
321
            $res
322
        );
323
    }
324
325
    // isBlank
326
    public function testSelectFilterIsBlankFound()
327
    {
328
        // test data
329
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
330
            <http://s> <http://p1> _:foo .
331
        }');
332
333
        $res = $this->subjectUnderTest->query('
334
            SELECT ?s ?o WHERE {
335
                ?s <http://p1> ?o .
336
                FILTER (isBlank(?o))
337
            }
338
        ');
339
        $this->assertEquals(
340
            [
341
                'query_type' => 'select',
342
                'result' => [
343
                    'variables' => [
344
                        's', 'o',
345
                    ],
346
                    'rows' => [
347
                        [
348
                            's' => 'http://s',
349
                            's type' => 'uri',
350
                            'o' => $res['result']['rows'][0]['o'],
351
                            'o type' => 'bnode',
352
                        ],
353
                    ],
354
                ],
355
                'query_time' => $res['query_time'],
356
            ],
357
            $res
358
        );
359
    }
360
361
    // isBlank
362
    public function testSelectFilterIsBlankNotFound()
363
    {
364
        // test data
365
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
366
            <http://s> <http://p1> <http://foo> .
367
        }');
368
369
        $res = $this->subjectUnderTest->query('
370
            SELECT ?s ?o WHERE {
371
                ?s <http://p1> ?o .
372
                FILTER (isBlank(?o))
373
            }
374
        ');
375
        $this->assertEquals(
376
            [
377
                'query_type' => 'select',
378
                'result' => [
379
                    'variables' => [
380
                        's', 'o',
381
                    ],
382
                    'rows' => [],
383
                ],
384
                'query_time' => $res['query_time'],
385
            ],
386
            $res
387
        );
388
    }
389
390
    // isIri
391
    public function testSelectFilterIsIriFound()
392
    {
393
        // test data
394
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
395
            <http://s> <http://p1> <urn:id> .
396
        }');
397
398
        $res = $this->subjectUnderTest->query('
399
            SELECT ?s ?o WHERE {
400
                ?s <http://p1> ?o .
401
                FILTER (isIri(?o))
402
            }
403
        ');
404
        $this->assertEquals(
405
            [
406
                'query_type' => 'select',
407
                'result' => [
408
                    'variables' => [
409
                        's', 'o',
410
                    ],
411
                    'rows' => [
412
                        [
413
                            's' => 'http://s',
414
                            's type' => 'uri',
415
                            'o' => 'urn:id',
416
                            'o type' => 'uri',
417
                        ],
418
                    ],
419
                ],
420
                'query_time' => $res['query_time'],
421
            ],
422
            $res
423
        );
424
    }
425
426
    // isIri
427
    public function testSelectFilterIsIriNotFound()
428
    {
429
        // test data
430
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
431
            <http://s> <http://p1> "foo" .
432
        }');
433
434
        $res = $this->subjectUnderTest->query('
435
            SELECT ?s ?o WHERE {
436
                ?s <http://p1> ?o .
437
                FILTER (isIri(?o))
438
            }
439
        ');
440
        $this->assertEquals(
441
            [
442
                'query_type' => 'select',
443
                'result' => [
444
                    'variables' => [
445
                        's', 'o',
446
                    ],
447
                    'rows' => [],
448
                ],
449
                'query_time' => $res['query_time'],
450
            ],
451
            $res
452
        );
453
    }
454
455
    // isLiteral
456
    public function testSelectFilterIsLiteralFound()
457
    {
458
        // test data
459
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
460
            <http://s> <http://p1> "foo" .
461
        }');
462
463
        $res = $this->subjectUnderTest->query('
464
            SELECT ?s ?o WHERE {
465
                ?s <http://p1> ?o .
466
                FILTER (isLiteral(?o))
467
            }
468
        ');
469
        $this->assertEquals(
470
            [
471
                'query_type' => 'select',
472
                'result' => [
473
                    'variables' => [
474
                        's', 'o',
475
                    ],
476
                    'rows' => [
477
                        [
478
                            's' => 'http://s',
479
                            's type' => 'uri',
480
                            'o' => 'foo',
481
                            'o type' => 'literal',
482
                        ],
483
                    ],
484
                ],
485
                'query_time' => $res['query_time'],
486
            ],
487
            $res
488
        );
489
    }
490
491
    // isLiteral
492
    public function testSelectFilterIsLiteralNotFound()
493
    {
494
        // test data
495
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
496
            <http://s> <http://p1> <http://foo> .
497
        }');
498
499
        $res = $this->subjectUnderTest->query('
500
            SELECT ?s ?o WHERE {
501
                ?s <http://p1> ?o .
502
                FILTER (isLiteral(?o))
503
            }
504
        ');
505
        $this->assertEquals(
506
            [
507
                'query_type' => 'select',
508
                'result' => [
509
                    'variables' => [
510
                        's', 'o',
511
                    ],
512
                    'rows' => [],
513
                ],
514
                'query_time' => $res['query_time'],
515
            ],
516
            $res
517
        );
518
    }
519
520
    // isUri
521
    public function testSelectFilterIsUriFound()
522
    {
523
        // test data
524
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
525
            <http://s> <http://p1> <urn:id> .
526
        }');
527
528
        $res = $this->subjectUnderTest->query('
529
            SELECT ?s ?o WHERE {
530
                ?s <http://p1> ?o .
531
                FILTER (isUri(?o))
532
            }
533
        ');
534
        $this->assertEquals(
535
            [
536
                'query_type' => 'select',
537
                'result' => [
538
                    'variables' => [
539
                        's', 'o',
540
                    ],
541
                    'rows' => [
542
                        [
543
                            's' => 'http://s',
544
                            's type' => 'uri',
545
                            'o' => 'urn:id',
546
                            'o type' => 'uri',
547
                        ],
548
                    ],
549
                ],
550
                'query_time' => $res['query_time'],
551
            ],
552
            $res
553
        );
554
    }
555
556
    // isUri
557
    public function testSelectFilterIsUriNotFound()
558
    {
559
        // test data
560
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
561
            <http://s> <http://p1> "foo" .
562
        }');
563
564
        $res = $this->subjectUnderTest->query('
565
            SELECT ?s ?o WHERE {
566
                ?s <http://p1> ?o .
567
                FILTER (isUri(?o))
568
            }
569
        ');
570
        $this->assertEquals(
571
            [
572
                'query_type' => 'select',
573
                'result' => [
574
                    'variables' => [
575
                        's', 'o',
576
                    ],
577
                    'rows' => [],
578
                ],
579
                'query_time' => $res['query_time'],
580
            ],
581
            $res
582
        );
583
    }
584
585
    // lang: test behavior when using a language
586
    public function testSelectFilterLang()
587
    {
588
        // test data
589
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
590
            <http://s> <http://p1> "foo" .
591
            <http://s> <http://p1> "in de"@de .
592
            <http://s> <http://p1> "in en"@en .
593
        }');
594
595
        $res = $this->subjectUnderTest->query('
596
            SELECT ?s ?o WHERE {
597
                ?s <http://p1> ?o .
598
                FILTER (lang(?o) = "en")
599
            }
600
        ');
601
        $this->assertEquals(
602
            [
603
                'query_type' => 'select',
604
                'result' => [
605
                    'variables' => [
606
                        's', 'o',
607
                    ],
608
                    'rows' => [
609
                        [
610
                            's' => 'http://s',
611
                            's type' => 'uri',
612
                            'o' => 'in en',
613
                            'o type' => 'literal',
614
                            'o lang' => 'en',
615
                        ],
616
                    ],
617
                ],
618
                'query_time' => $res['query_time'],
619
            ],
620
            $res
621
        );
622
    }
623
624
    // langMatches
625
    public function testSelectFilterLangMatches()
626
    {
627
        // test data
628
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
629
            <http://s> <http://p1> "foo" .
630
            <http://s> <http://p1> "in de"@de .
631
            <http://s> <http://p1> "in en"@en .
632
        }');
633
634
        $res = $this->subjectUnderTest->query('
635
            SELECT ?s ?o WHERE {
636
                ?s <http://p1> ?o .
637
                FILTER langMatches (lang(?o), "en")
638
            }
639
        ');
640
        $this->assertEquals(
641
            [
642
                'query_type' => 'select',
643
                'result' => [
644
                    'variables' => [
645
                        's', 'o',
646
                    ],
647
                    'rows' => [
648
                        [
649
                            's' => 'http://s',
650
                            's type' => 'uri',
651
                            'o' => 'in en',
652
                            'o type' => 'literal',
653
                            'o lang' => 'en',
654
                        ],
655
                    ],
656
                ],
657
                'query_time' => $res['query_time'],
658
            ],
659
            $res
660
        );
661
    }
662
663
    // regex
664
    public function testSelectFilterRegex()
665
    {
666
        // test data
667
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
668
            <http://s> <http://p1> "Alice".
669
            <http://s2> <http://p1> "Bob" .
670
        }');
671
672
        $res = $this->subjectUnderTest->query('
673
            SELECT ?s ?o WHERE {
674
                ?s <http://p1> ?o .
675
                FILTER regex (?o, "^Ali")
676
            }
677
        ');
678
        $this->assertEquals(
679
            [
680
                'query_type' => 'select',
681
                'result' => [
682
                    'variables' => [
683
                        's', 'o',
684
                    ],
685
                    'rows' => [
686
                        [
687
                            's' => 'http://s',
688
                            's type' => 'uri',
689
                            'o' => 'Alice',
690
                            'o type' => 'literal',
691
                        ],
692
                    ],
693
                ],
694
                'query_time' => $res['query_time'],
695
            ],
696
            $res
697
        );
698
    }
699
700
    // regex
701
    public function testSelectFilterRegexWithModifier()
702
    {
703
        // test data
704
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
705
            <http://s> <http://p1> "Alice".
706
            <http://s2> <http://p1> "Bob" .
707
        }');
708
709
        $res = $this->subjectUnderTest->query('
710
            SELECT ?s ?o WHERE {
711
                ?s <http://p1> ?o .
712
                FILTER regex (?o, "^ali", "i")
713
            }
714
        ');
715
        $this->assertEquals(
716
            [
717
                'query_type' => 'select',
718
                'result' => [
719
                    'variables' => [
720
                        's', 'o',
721
                    ],
722
                    'rows' => [
723
                        [
724
                            's' => 'http://s',
725
                            's type' => 'uri',
726
                            'o' => 'Alice',
727
                            'o type' => 'literal',
728
                        ],
729
                    ],
730
                ],
731
                'query_time' => $res['query_time'],
732
            ],
733
            $res
734
        );
735
    }
736
737
    // str
738
    public function testSelectFilterStr()
739
    {
740
        // test data
741
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
742
            <http://s> <http://p1> "foo" .
743
            <http://s> <http://p1> "in de"@de .
744
            <http://s> <http://p1> "in en"@en .
745
        }');
746
747
        $res = $this->subjectUnderTest->query('
748
            SELECT ?s ?o WHERE {
749
                ?s <http://p1> ?o .
750
                FILTER (str(?o) = "in en")
751
            }
752
        ');
753
        $this->assertEquals(
754
            [
755
                'query_type' => 'select',
756
                'result' => [
757
                    'variables' => [
758
                        's', 'o',
759
                    ],
760
                    'rows' => [
761
                        [
762
                            's' => 'http://s',
763
                            's type' => 'uri',
764
                            'o' => 'in en',
765
                            'o type' => 'literal',
766
                            'o lang' => 'en',
767
                        ],
768
                    ],
769
                ],
770
                'query_time' => $res['query_time'],
771
            ],
772
            $res
773
        );
774
    }
775
776
    // str
777
    public function testSelectFilterStrNotFound()
778
    {
779
        // test data
780
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
781
            <http://s> <http://p1> "foo" .
782
            <http://s> <http://p1> "in de"@de .
783
            <http://s> <http://p1> "in en"@en .
784
        }');
785
786
        $res = $this->subjectUnderTest->query('
787
            SELECT ?s ?o WHERE {
788
                ?s <http://p1> ?o .
789
                FILTER (str(?o) = "in it")
790
            }
791
        ');
792
        $this->assertEquals(
793
            [
794
                'query_type' => 'select',
795
                'result' => [
796
                    'variables' => [
797
                        's', 'o',
798
                    ],
799
                    'rows' => [],
800
                ],
801
                'query_time' => $res['query_time'],
802
            ],
803
            $res
804
        );
805
    }
806
807
    // >
808
    public function testSelectFilterRelationalGreaterThan()
809
    {
810
        // test data
811
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
812
            <http://container1> <http://weight> "150" .
813
            <http://container2> <http://weight> "50" .
814
        }');
815
816
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
817
            ?c <http://weight> ?w .
818
819
            FILTER (?w > 100)
820
        }');
821
        $this->assertEquals(
822
            [
823
                'query_type' => 'select',
824
                'result' => [
825
                    'variables' => [
826
                        'c',
827
                    ],
828
                    'rows' => [
829
                        [
830
                            'c' => 'http://container1',
831
                            'c type' => 'uri',
832
                        ],
833
                    ],
834
                ],
835
                'query_time' => $res['query_time'],
836
            ],
837
            $res
838
        );
839
    }
840
841
    // <
842
    public function testSelectFilterRelationalSmallerThan()
843
    {
844
        // test data
845
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
846
            <http://container1> <http://weight> "150" .
847
            <http://container2> <http://weight> "50" .
848
        }');
849
850
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
851
            ?c <http://weight> ?w .
852
853
            FILTER (?w < 100)
854
        }');
855
        $this->assertEquals(
856
            [
857
                'query_type' => 'select',
858
                'result' => [
859
                    'variables' => [
860
                        'c',
861
                    ],
862
                    'rows' => [
863
                        [
864
                            'c' => 'http://container2',
865
                            'c type' => 'uri',
866
                        ],
867
                    ],
868
                ],
869
                'query_time' => $res['query_time'],
870
            ],
871
            $res
872
        );
873
    }
874
875
    // <
876
    public function testSelectFilterRelationalSmallerThan2()
877
    {
878
        // test data
879
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
880
            <http://container1> <http://weight> "150" .
881
            <http://container2> <http://weight> "50" .
882
        }');
883
884
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
885
            ?c <http://weight> ?w .
886
887
            FILTER (?w < 100 && ?w > 10)
888
        }');
889
        $this->assertEquals(
890
            [
891
                [
892
                    'c' => 'http://container2',
893
                    'c type' => 'uri',
894
                ],
895
            ],
896
            $res['result']['rows']
897
        );
898
    }
899
900
    // =
901
    public function testSelectFilterRelationalEqual()
902
    {
903
        // test data
904
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
905
            <http://container1> <http://weight> "150" .
906
            <http://container2> <http://weight> "50" .
907
        }');
908
909
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
910
            ?c <http://weight> ?w .
911
912
            FILTER (?w = 150)
913
        }');
914
        $this->assertEquals(
915
            [
916
                'query_type' => 'select',
917
                'result' => [
918
                    'variables' => [
919
                        'c',
920
                    ],
921
                    'rows' => [
922
                        [
923
                            'c' => 'http://container1',
924
                            'c type' => 'uri',
925
                        ],
926
                    ],
927
                ],
928
                'query_time' => $res['query_time'],
929
            ],
930
            $res
931
        );
932
    }
933
934
    // !=
935
    public function testSelectFilterRelationalNotEqual()
936
    {
937
        // test data
938
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
939
            <http://container1> <http://weight> "150" .
940
            <http://container2> <http://weight> "50" .
941
        }');
942
943
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
944
            ?c <http://weight> ?w .
945
946
            FILTER (?w != 150)
947
        }');
948
        $this->assertEquals(
949
            [
950
                'query_type' => 'select',
951
                'result' => [
952
                    'variables' => [
953
                        'c',
954
                    ],
955
                    'rows' => [
956
                        [
957
                            'c' => 'http://container2',
958
                            'c type' => 'uri',
959
                        ],
960
                    ],
961
                ],
962
                'query_time' => $res['query_time'],
963
            ],
964
            $res
965
        );
966
    }
967
968
    /*
969
     * SELECT COUNT
970
     */
971
972
    public function testSelectCount()
973
    {
974
        // test data
975
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
976
            <http://person1> <http://name> "baz" .
977
            <http://person2> <http://name> "baz" .
978
            <http://person3> <http://name> "baz" .
979
        }');
980
981
        $res = $this->subjectUnderTest->query('
982
            SELECT COUNT(?s) AS ?count WHERE {
983
                ?s <http://name> "baz" .
984
            }
985
            ORDER BY DESC(?count)
986
        ');
987
        $this->assertEquals(
988
            [
989
                'query_type' => 'select',
990
                'result' => [
991
                    'variables' => [
992
                        'count',
993
                    ],
994
                    'rows' => [
995
                        [
996
                            'count' => '3',
997
                            'count type' => 'literal',
998
                        ],
999
                    ],
1000
                ],
1001
                'query_time' => $res['query_time'],
1002
            ],
1003
            $res
1004
        );
1005
    }
1006
1007
    /*
1008
     * GROUP BY
1009
     */
1010
1011
    public function testSelectGroupBy()
1012
    {
1013
        $query = 'SELECT ?who COUNT(?person) as ?persons WHERE {
1014
                ?who <http://knows> ?person .
1015
            }
1016
            GROUP BY ?who
1017
        ';
1018
1019
        // test data
1020
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1021
            <http://person1> <http://knows> <http://person2>, <http://person3> .
1022
            <http://person2> <http://knows> <http://person3> .
1023
        }');
1024
1025
        $res = $this->subjectUnderTest->query($query);
1026
        $this->assertEquals(
1027
            [
1028
                'query_type' => 'select',
1029
                'result' => [
1030
                    'variables' => [
1031
                        'who',
1032
                        'persons',
1033
                    ],
1034
                    'rows' => [
1035
                        [
1036
                            'who' => 'http://person1',
1037
                            'who type' => 'uri',
1038
                            'persons' => '2',
1039
                            'persons type' => 'literal',
1040
                        ],
1041
                        [
1042
                            'who' => 'http://person2',
1043
                            'who type' => 'uri',
1044
                            'persons' => '1',
1045
                            'persons type' => 'literal',
1046
                        ],
1047
                    ],
1048
                ],
1049
                'query_time' => $res['query_time'],
1050
            ],
1051
            $res
1052
        );
1053
    }
1054
1055
    /*
1056
     * OFFSET and LIMIT
1057
     */
1058
1059
    public function testSelectOffset()
1060
    {
1061
        // test data
1062
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1063
            <http://person1> <http://id> "1" .
1064
            <http://person3> <http://id> "3" .
1065
            <http://person2> <http://id> "2" .
1066
        }');
1067
1068
        $res = $this->subjectUnderTest->query('
1069
            SELECT * WHERE { ?s ?p ?o . }
1070
            OFFSET 1
1071
        ');
1072
1073
        $this->assertEquals(
1074
            [
1075
                'query_type' => 'select',
1076
                'result' => [
1077
                    'variables' => [
1078
                        's', 'p', 'o',
1079
                    ],
1080
                    'rows' => [
1081
                        [
1082
                            's' => 'http://person3',
1083
                            's type' => 'uri',
1084
                            'p' => 'http://id',
1085
                            'p type' => 'uri',
1086
                            'o' => '3',
1087
                            'o type' => 'literal',
1088
                        ],
1089
                        [
1090
                            's' => 'http://person2',
1091
                            's type' => 'uri',
1092
                            'p' => 'http://id',
1093
                            'p type' => 'uri',
1094
                            'o' => '2',
1095
                            'o type' => 'literal',
1096
                        ],
1097
                    ],
1098
                ],
1099
                'query_time' => $res['query_time'],
1100
            ],
1101
            $res
1102
        );
1103
    }
1104
1105
    public function testSelectOffsetLimit()
1106
    {
1107
        // test data
1108
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1109
            <http://person1> <http://id> "1" .
1110
            <http://person3> <http://id> "3" .
1111
            <http://person2> <http://id> "2" .
1112
        }');
1113
1114
        $res = $this->subjectUnderTest->query('
1115
            SELECT * WHERE { ?s ?p ?o . }
1116
            OFFSET 1 LIMIT 2
1117
        ');
1118
1119
        $this->assertEquals(
1120
            [
1121
                'query_type' => 'select',
1122
                'result' => [
1123
                    'variables' => [
1124
                        's', 'p', 'o',
1125
                    ],
1126
                    'rows' => [
1127
                        [
1128
                            's' => 'http://person3',
1129
                            's type' => 'uri',
1130
                            'p' => 'http://id',
1131
                            'p type' => 'uri',
1132
                            'o' => '3',
1133
                            'o type' => 'literal',
1134
                        ],
1135
                        [
1136
                            's' => 'http://person2',
1137
                            's type' => 'uri',
1138
                            'p' => 'http://id',
1139
                            'p type' => 'uri',
1140
                            'o' => '2',
1141
                            'o type' => 'literal',
1142
                        ],
1143
                    ],
1144
                ],
1145
                'query_time' => $res['query_time'],
1146
            ],
1147
            $res
1148
        );
1149
    }
1150
1151
    public function testSelectLimit()
1152
    {
1153
        // test data
1154
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1155
            <http://person1> <http://id> "1" .
1156
            <http://person3> <http://id> "3" .
1157
            <http://person2> <http://id> "2" .
1158
        }');
1159
1160
        $res = $this->subjectUnderTest->query('
1161
            SELECT * WHERE { ?s ?p ?o . }
1162
            LIMIT 2
1163
        ');
1164
1165
        $this->assertEquals(
1166
            [
1167
                'query_type' => 'select',
1168
                'result' => [
1169
                    'variables' => [
1170
                        's', 'p', 'o',
1171
                    ],
1172
                    'rows' => [
1173
                        [
1174
                            's' => 'http://person1',
1175
                            's type' => 'uri',
1176
                            'p' => 'http://id',
1177
                            'p type' => 'uri',
1178
                            'o' => '1',
1179
                            'o type' => 'literal',
1180
                        ],
1181
                        [
1182
                            's' => 'http://person3',
1183
                            's type' => 'uri',
1184
                            'p' => 'http://id',
1185
                            'p type' => 'uri',
1186
                            'o' => '3',
1187
                            'o type' => 'literal',
1188
                        ],
1189
                    ],
1190
                ],
1191
                'query_time' => $res['query_time'],
1192
            ],
1193
            $res
1194
        );
1195
    }
1196
1197
    /*
1198
     * ORDER BY
1199
     */
1200
1201
    public function testSelectOrderByAsc()
1202
    {
1203
        // test data
1204
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1205
            <http://person1> <http://id> "1" .
1206
            <http://person3> <http://id> "3" .
1207
            <http://person2> <http://id> "2" .
1208
        }');
1209
1210
        $res = $this->subjectUnderTest->query('
1211
            SELECT * WHERE {
1212
                ?s <http://id> ?id .
1213
            }
1214
            ORDER BY ASC(?id)
1215
        ');
1216
        $this->assertEquals(
1217
            [
1218
                'query_type' => 'select',
1219
                'result' => [
1220
                    'variables' => [
1221
                        's',
1222
                        'id',
1223
                    ],
1224
                    'rows' => [
1225
                        [
1226
                            's' => 'http://person1',
1227
                            's type' => 'uri',
1228
                            'id' => '1',
1229
                            'id type' => 'literal',
1230
                        ],
1231
                        [
1232
                            's' => 'http://person2',
1233
                            's type' => 'uri',
1234
                            'id' => '2',
1235
                            'id type' => 'literal',
1236
                        ],
1237
                        [
1238
                            's' => 'http://person3',
1239
                            's type' => 'uri',
1240
                            'id' => '3',
1241
                            'id type' => 'literal',
1242
                        ],
1243
                    ],
1244
                ],
1245
                'query_time' => $res['query_time'],
1246
            ],
1247
            $res
1248
        );
1249
    }
1250
1251
    public function testSelectOrderByDesc()
1252
    {
1253
        // test data
1254
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1255
            <http://person1> <http://id> "1" .
1256
            <http://person3> <http://id> "3" .
1257
            <http://person2> <http://id> "2" .
1258
        }');
1259
1260
        $res = $this->subjectUnderTest->query('
1261
            SELECT * WHERE {
1262
                ?s <http://id> ?id .
1263
            }
1264
            ORDER BY DESC(?id)
1265
        ');
1266
        $this->assertEquals(
1267
            [
1268
                'query_type' => 'select',
1269
                'result' => [
1270
                    'variables' => [
1271
                        's',
1272
                        'id',
1273
                    ],
1274
                    'rows' => [
1275
                        [
1276
                            's' => 'http://person3',
1277
                            's type' => 'uri',
1278
                            'id' => '3',
1279
                            'id type' => 'literal',
1280
                        ],
1281
                        [
1282
                            's' => 'http://person2',
1283
                            's type' => 'uri',
1284
                            'id' => '2',
1285
                            'id type' => 'literal',
1286
                        ],
1287
                        [
1288
                            's' => 'http://person1',
1289
                            's type' => 'uri',
1290
                            'id' => '1',
1291
                            'id type' => 'literal',
1292
                        ],
1293
                    ],
1294
                ],
1295
                'query_time' => $res['query_time'],
1296
            ],
1297
            $res
1298
        );
1299
    }
1300
1301
    public function testSelectOrderByWithoutContent()
1302
    {
1303
        $res = $this->subjectUnderTest->query('
1304
            SELECT * WHERE {
1305
                ?s <http://id> ?id .
1306
            }
1307
            ORDER BY
1308
        ');
1309
1310
        // query false, therefore 0 as result
1311
        $this->assertEquals(0, $res);
1312
    }
1313
1314
    /*
1315
     * PREFIX
1316
     */
1317
1318
    public function testSelectPrefix()
1319
    {
1320
        // test data
1321
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1322
            <http://person1> <http://example.com/kennt> <http://person2> .
1323
        }');
1324
1325
        $res = $this->subjectUnderTest->query('
1326
            PREFIX ex: <http://example.com/>
1327
            SELECT * WHERE {
1328
                ?s ex:kennt ?o
1329
            }
1330
        ');
1331
1332
        $this->assertEquals(
1333
            [
1334
                'query_type' => 'select',
1335
                'result' => [
1336
                    'variables' => [
1337
                        's', 'o',
1338
                    ],
1339
                    'rows' => [
1340
                        [
1341
                            's' => 'http://person1',
1342
                            's type' => 'uri',
1343
                            'o' => 'http://person2',
1344
                            'o type' => 'uri',
1345
                        ],
1346
                    ],
1347
                ],
1348
                'query_time' => $res['query_time'],
1349
            ],
1350
            $res
1351
        );
1352
    }
1353
1354
    /*
1355
     * UNION
1356
     */
1357
1358
    public function testSelectUnion()
1359
    {
1360
        // test data
1361
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1362
            <http://person1> <http://id> "1" .
1363
            <http://person3> <http://id> "3" .
1364
            <http://person2> <http://id> "2" .
1365
        }');
1366
1367
        $res = $this->subjectUnderTest->query('
1368
            SELECT * WHERE {
1369
                {
1370
                    ?p <http://id> "1" .
1371
                } UNION {
1372
                    ?p <http://id> "3" .
1373
                }
1374
            }
1375
        ');
1376
1377
        $this->assertEquals(
1378
            [
1379
                'query_type' => 'select',
1380
                'result' => [
1381
                    'variables' => [
1382
                        'p',
1383
                    ],
1384
                    'rows' => [
1385
                        [
1386
                            'p' => 'http://person1',
1387
                            'p type' => 'uri',
1388
                        ],
1389
                        [
1390
                            'p' => 'http://person3',
1391
                            'p type' => 'uri',
1392
                        ],
1393
                    ],
1394
                ],
1395
                'query_time' => $res['query_time'],
1396
            ],
1397
            $res
1398
        );
1399
    }
1400
1401
    /*
1402
     * Tests using certain queries with SELECT FROM WHERE and not just SELECT WHERE
1403
     */
1404
1405
    public function testSelectOrderByAscWithFromClause()
1406
    {
1407
        // test data
1408
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1409
            <http://person1> <http://id> "1" .
1410
            <http://person3> <http://id> "3" .
1411
            <http://person2> <http://id> "2" .
1412
        }');
1413
1414
        $res = $this->subjectUnderTest->query('
1415
            SELECT * FROM <http://example.com/> WHERE {
1416
                ?s <http://id> ?id .
1417
            }
1418
            ORDER BY ASC(?id)
1419
        ');
1420
        $this->assertEquals(
1421
            [
1422
                'query_type' => 'select',
1423
                'result' => [
1424
                    'variables' => [
1425
                        's',
1426
                        'id',
1427
                    ],
1428
                    'rows' => [
1429
                        [
1430
                            's' => 'http://person1',
1431
                            's type' => 'uri',
1432
                            'id' => '1',
1433
                            'id type' => 'literal',
1434
                        ],
1435
                        [
1436
                            's' => 'http://person2',
1437
                            's type' => 'uri',
1438
                            'id' => '2',
1439
                            'id type' => 'literal',
1440
                        ],
1441
                        [
1442
                            's' => 'http://person3',
1443
                            's type' => 'uri',
1444
                            'id' => '3',
1445
                            'id type' => 'literal',
1446
                        ],
1447
                    ],
1448
                ],
1449
                'query_time' => $res['query_time'],
1450
            ],
1451
            $res
1452
        );
1453
    }
1454
1455
    /**
1456
     * Select Distinct
1457
     *
1458
     * @see https://www.w3.org/TR/rdf-sparql-query/#modDistinct
1459
     */
1460
    public function testSelectDistinct()
1461
    {
1462
        // test data
1463
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1464
            <http://person1> <http://example.com/kennt> "Test" .
1465
            <http://person2> <http://example.com/kennt> "Test" .
1466
            <http://person3> <http://example.com/kennt> "Test" .
1467
            <http://person4> <http://example.com/kennt> "Test2" .
1468
        }');
1469
1470
        $res = $this->subjectUnderTest->query('
1471
            PREFIX ex: <http://example.com/>
1472
            SELECT DISTINCT ?name WHERE {
1473
                ?s ex:kennt ?name
1474
            }
1475
        ');
1476
1477
        $this->assertEquals(
1478
            [
1479
                ['name' => 'Test', 'name type' => 'literal'],
1480
                ['name' => 'Test2', 'name type' => 'literal'],
1481
            ],
1482
            $res['result']['rows']
1483
        );
1484
    }
1485
}
1486