Passed
Push — master ( 374fd3...a58c7c )
by Konrad
25:54
created

testMultipleInsertsSameStore()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 27
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 42
rs 9.488
1
<?php
2
3
/**
4
 * This file is part of the sweetrdf/InMemoryStoreSqlite package and licensed under
5
 * the terms of the GPL-2 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 Exception;
17
use simpleRdf\DataFactory;
18
use sweetrdf\InMemoryStoreSqlite\NamespaceHelper;
19
use sweetrdf\InMemoryStoreSqlite\Store\InMemoryStoreSqlite;
20
use Tests\TestCase;
21
22
/**
23
 * Tests for query method - focus on INSERT INTO queries.
24
 */
25
class InsertIntoQueryTest extends TestCase
26
{
27
    protected function setUp(): void
28
    {
29
        parent::setUp();
30
31
        $this->subjectUnderTest = InMemoryStoreSqlite::createInstance();
32
    }
33
34
    public function testInsertInto()
35
    {
36
        // test data
37
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
38
            <http://s> <http://p1> "baz" .
39
        }');
40
41
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
42
        $this->assertEquals(1, \count($res['result']['rows']));
43
    }
44
45
    public function testInsertIntoUriTriple()
46
    {
47
        // test data
48
        $this->subjectUnderTest->query('INSERT INTO <http://ex> { <http://s> <http://p> <http://o> .}');
49
50
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
51
        $this->assertEquals(
52
            [
53
                [
54
                    's' => 'http://s',
55
                    's type' => 'uri',
56
                    'p' => 'http://p',
57
                    'p type' => 'uri',
58
                    'o' => 'http://o',
59
                    'o type' => 'uri',
60
                ],
61
            ],
62
            $res['result']['rows']
63
        );
64
    }
65
66
    public function testInsertIntoShortenedUri()
67
    {
68
        // test data
69
        $this->subjectUnderTest->query('INSERT INTO <http://ex> { <#make> <#me> <#happy> .}');
70
71
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
72
        $this->assertEquals(
73
            [
74
                [
75
                    's' => NamespaceHelper::BASE_NAMESPACE.'#make',
76
                    's type' => 'uri',
77
                    'p' => NamespaceHelper::BASE_NAMESPACE.'#me',
78
                    'p type' => 'uri',
79
                    'o' => NamespaceHelper::BASE_NAMESPACE.'#happy',
80
                    'o type' => 'uri',
81
                ],
82
            ],
83
            $res['result']['rows']
84
        );
85
    }
86
87
    public function testInsertIntoPrefixedUri()
88
    {
89
        // test data
90
        $query = '
91
            PREFIX ex: <http://ex/>
92
            INSERT INTO <http://ex> { <http://s> rdf:type ex:Person .}
93
        ';
94
        $this->subjectUnderTest->query($query);
95
96
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
97
        $this->assertEquals(
98
            [
99
                [
100
                    's' => 'http://s',
101
                    's type' => 'uri',
102
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
103
                    'p type' => 'uri',
104
                    'o' => 'http://ex/Person',
105
                    'o type' => 'uri',
106
                ],
107
            ],
108
            $res['result']['rows']
109
        );
110
    }
111
112
    /**
113
     * Tests handling of rdf:type and a, in context of ":foo a owl:Ontology".
114
     */
115
    public function testInsertIntoRdfTypeAndA()
116
    {
117
        // test data
118
        $query = '
119
            PREFIX ex: <http://ex/>
120
            INSERT INTO <http://ex> {
121
                <http://foo> rdf:type ex:Person .
122
                <http://bar> a ex:Person .
123
            }
124
        ';
125
        $this->subjectUnderTest->query($query);
126
127
        $res = $this->subjectUnderTest->query('SELECT * WHERE {?s ?p ?o.}');
128
        $this->assertEquals(
129
            [
130
                [
131
                    's' => 'http://foo',
132
                    's type' => 'uri',
133
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
134
                    'p type' => 'uri',
135
                    'o' => 'http://ex/Person',
136
                    'o type' => 'uri',
137
                ],
138
                [
139
                    's' => 'http://bar',
140
                    's type' => 'uri',
141
                    // a was translated to rdf:type on insertion
142
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
143
                    'p type' => 'uri',
144
                    'o' => 'http://ex/Person',
145
                    'o type' => 'uri',
146
                ],
147
            ],
148
            $res['result']['rows']
149
        );
150
151
        // asking for resources via a ...
152
        $res = $this->subjectUnderTest->query('SELECT ?iri WHERE {?iri a <http://ex/Person>}');
153
        $this->assertEquals(
154
            [['iri' => 'http://foo', 'iri type' => 'uri'], ['iri' => 'http://bar', 'iri type' => 'uri'],],
155
            $res['result']['rows']
156
        );
157
        // and rdf:type ...
158
        $res = $this->subjectUnderTest->query('SELECT ?iri WHERE {?iri rdf:type <http://ex/Person>}');
159
        $this->assertEquals(
160
            [['iri' => 'http://foo', 'iri type' => 'uri'], ['iri' => 'http://bar', 'iri type' => 'uri'],],
161
            $res['result']['rows']
162
        );
163
    }
164
165
    public function testInsertIntoNumbers()
166
    {
167
        // test data
168
        $this->subjectUnderTest->query('INSERT INTO <http://ex> {
169
            <http://s> <http://foo> 1 .
170
            <http://s> <http://foo> 2.0 .
171
            <http://s> <http://foo> "3" .
172
        }');
173
174
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
175
        $this->assertEquals(
176
            [
177
                [
178
                    's' => 'http://s',
179
                    's type' => 'uri',
180
                    'p' => 'http://foo',
181
                    'p type' => 'uri',
182
                    'o' => '1',
183
                    'o type' => 'literal',
184
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
185
                ],
186
                [
187
                    's' => 'http://s',
188
                    's type' => 'uri',
189
                    'p' => 'http://foo',
190
                    'p type' => 'uri',
191
                    'o' => '2.0',
192
                    'o type' => 'literal',
193
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#decimal',
194
                ],
195
                [
196
                    's' => 'http://s',
197
                    's type' => 'uri',
198
                    'p' => 'http://foo',
199
                    'p type' => 'uri',
200
                    'o' => '3',
201
                    'o type' => 'literal',
202
                ],
203
            ],
204
            $res['result']['rows']
205
        );
206
    }
207
208
    public function testInsertIntoObjectWithDatatype()
209
    {
210
        // test data
211
        $this->subjectUnderTest->query('INSERT INTO <http://ex> {
212
            <http://s> <http://foo> "4"^^xsd:integer .
213
        }');
214
215
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
216
        $this->assertEquals(
217
            [
218
                [
219
                    's' => 'http://s',
220
                    's type' => 'uri',
221
                    'p' => 'http://foo',
222
                    'p type' => 'uri',
223
                    'o' => '4',
224
                    'o type' => 'literal',
225
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
226
                ],
227
            ],
228
            $res['result']['rows']
229
        );
230
    }
231
232
    public function testInsertIntoObjectWithLanguage()
233
    {
234
        // test data
235
        $this->subjectUnderTest->query('INSERT INTO <http://ex> {
236
            <http://s> <http://foo> "5"@en .
237
        }');
238
239
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
240
        $this->assertEquals(
241
            [
242
                [
243
                    's' => 'http://s',
244
                    's type' => 'uri',
245
                    'p' => 'http://foo',
246
                    'p type' => 'uri',
247
                    'o' => '5',
248
                    'o type' => 'literal',
249
                    'o lang' => 'en',
250
                ],
251
            ],
252
            $res['result']['rows']
253
        );
254
    }
255
256
    public function testInsertIntoBlankNode1()
257
    {
258
        // test data
259
        $this->subjectUnderTest->query('INSERT INTO <http://ex> {
260
            _:foo <http://foo> "6" .
261
        }');
262
263
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex> {?s ?p ?o.}');
264
        $this->assertEquals(
265
            [
266
                [
267
                    's' => $res['result']['rows'][0]['s'], // blank node ID is dynamic
268
                    's type' => 'bnode',
269
                    'p' => 'http://foo',
270
                    'p type' => 'uri',
271
                    'o' => '6',
272
                    'o type' => 'literal',
273
                ],
274
            ],
275
            $res['result']['rows']
276
        );
277
    }
278
279
    public function testInsertIntoBlankNode2()
280
    {
281
        // test data
282
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
283
            <http://s> <http://p1> [
284
                <http://foo> <http://bar>
285
            ] .
286
        }');
287
288
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
289
290
        // because bnode ID is random, we check only its structure
291
        $this->assertTrue(isset($res['result']['rows'][0]));
292
        $this->assertEquals(1, preg_match('/_:[a-z0-9]+_[a-z0-9]+/', $res['result']['rows'][0]['o']));
293
294
        $this->assertEquals(
295
            [
296
                [
297
                    's' => 'http://s',
298
                    's type' => 'uri',
299
                    'p' => 'http://p1',
300
                    'p type' => 'uri',
301
                    'o' => $res['result']['rows'][0]['o'],
302
                    'o type' => 'bnode',
303
                ],
304
                [
305
                    's' => $res['result']['rows'][0]['o'],
306
                    's type' => 'bnode',
307
                    'p' => 'http://foo',
308
                    'p type' => 'uri',
309
                    'o' => 'http://bar',
310
                    'o type' => 'uri',
311
                ],
312
            ],
313
            $res['result']['rows']
314
        );
315
    }
316
317
    public function testInsertIntoBlankNode3()
318
    {
319
        // test data
320
        $this->subjectUnderTest->query('
321
            PREFIX ex: <http://ex/>
322
            INSERT INTO <http://ex/> {
323
                ex:3 ex:action [
324
                    ex:query  <agg-avg-01.rq> ;
325
                    ex:data   <agg-numeric.ttl>
326
                ] .
327
            }
328
        ');
329
330
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
331
332
        $this->assertEquals(
333
            [
334
                [
335
                    's' => 'http://ex/3',
336
                    's type' => 'uri',
337
                    'p' => 'http://ex/action',
338
                    'p type' => 'uri',
339
                    'o' => $res['result']['rows'][0]['o'],
340
                    'o type' => 'bnode',
341
                ],
342
                [
343
                    's' => $res['result']['rows'][0]['o'],
344
                    's type' => 'bnode',
345
                    'p' => 'http://ex/query',
346
                    'p type' => 'uri',
347
                    'o' => NamespaceHelper::BASE_NAMESPACE.'agg-avg-01.rq',
348
                    'o type' => 'uri',
349
                ],
350
                [
351
                    's' => $res['result']['rows'][0]['o'],
352
                    's type' => 'bnode',
353
                    'p' => 'http://ex/data',
354
                    'p type' => 'uri',
355
                    'o' => NamespaceHelper::BASE_NAMESPACE.'agg-numeric.ttl',
356
                    'o type' => 'uri',
357
                ],
358
            ],
359
            $res['result']['rows']
360
        );
361
    }
362
363
    public function testInsertIntoDate()
364
    {
365
        // test data
366
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
367
            <http://s> <http://p1> "2009-05-28T18:03:38+09:00" .
368
            <http://s> <http://p1> "2009-05-28T18:03:38+09:00GMT" .
369
            <http://s> <http://p1> "21 August 2007" .
370
        }');
371
372
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
373
374
        $this->assertEquals(
375
            [
376
                'query_type' => 'select',
377
                'result' => [
378
                    'variables' => ['s', 'p', 'o'],
379
                    'rows' => [
380
                        [
381
                            's' => 'http://s',
382
                            's type' => 'uri',
383
                            'p' => 'http://p1',
384
                            'p type' => 'uri',
385
                            'o' => '2009-05-28T18:03:38+09:00',
386
                            'o type' => 'literal',
387
                        ],
388
                        [
389
                            's' => 'http://s',
390
                            's type' => 'uri',
391
                            'p' => 'http://p1',
392
                            'p type' => 'uri',
393
                            'o' => '2009-05-28T18:03:38+09:00GMT',
394
                            'o type' => 'literal',
395
                        ],
396
                        [
397
                            's' => 'http://s',
398
                            's type' => 'uri',
399
                            'p' => 'http://p1',
400
                            'p type' => 'uri',
401
                            'o' => '21 August 2007',
402
                            'o type' => 'literal',
403
                        ],
404
                    ],
405
                ],
406
            ],
407
            $res
408
        );
409
    }
410
411
    public function testInsertIntoList()
412
    {
413
        // test data
414
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
415
            <http://s> <http://p1> 1, 2, 3 .
416
        }');
417
418
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
419
420
        $this->assertEquals(
421
            [
422
                [
423
                    's' => 'http://s',
424
                    's type' => 'uri',
425
                    'p' => 'http://p1',
426
                    'p type' => 'uri',
427
                    'o' => '1',
428
                    'o type' => 'literal',
429
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
430
                ],
431
                [
432
                    's' => 'http://s',
433
                    's type' => 'uri',
434
                    'p' => 'http://p1',
435
                    'p type' => 'uri',
436
                    'o' => '2',
437
                    'o type' => 'literal',
438
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
439
                ],
440
                [
441
                    's' => 'http://s',
442
                    's type' => 'uri',
443
                    'p' => 'http://p1',
444
                    'p type' => 'uri',
445
                    'o' => '3',
446
                    'o type' => 'literal',
447
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
448
                ],
449
            ],
450
            $res['result']['rows']
451
        );
452
    }
453
454
    /**
455
     * Demonstrates that store can't save long values.
456
     */
457
    public function testInsertIntoLongValue()
458
    {
459
        // create long URI (ca. 250 chars)
460
        $longURI = 'http://'.hash('sha512', 'long')
461
            .hash('sha512', 'URI');
462
463
        $this->expectException(Exception::class);
464
465
        // test data
466
        $this->subjectUnderTest->query('INSERT INTO <http://graph> {
467
            <'.$longURI.'/s> <'.$longURI.'/p> <'.$longURI.'/o> ;
468
                             <'.$longURI.'/p2> <'.$longURI.'/o2> .
469
        ');
470
    }
471
472
    public function testInsertIntoListMoreComplex()
473
    {
474
        // test data
475
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
476
            _:b0  rdf:first  1 ;
477
                  rdf:rest   _:b1 .
478
            _:b1  rdf:first  2 ;
479
                  rdf:rest   _:b2 .
480
            _:b2  rdf:first  3 ;
481
                  rdf:rest   rdf:nil .
482
        }');
483
484
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
485
486
        $this->assertEquals(
487
            [
488
                [
489
                    's' => $res['result']['rows'][0]['s'],
490
                    's type' => 'bnode',
491
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first',
492
                    'p type' => 'uri',
493
                    'o' => '1',
494
                    'o type' => 'literal',
495
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
496
                ],
497
                [
498
                    's' => $res['result']['rows'][1]['s'],
499
                    's type' => 'bnode',
500
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest',
501
                    'p type' => 'uri',
502
                    'o' => $res['result']['rows'][1]['o'],
503
                    'o type' => 'bnode',
504
                ],
505
                [
506
                    's' => $res['result']['rows'][2]['s'],
507
                    's type' => 'bnode',
508
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first',
509
                    'p type' => 'uri',
510
                    'o' => '2',
511
                    'o type' => 'literal',
512
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
513
                ],
514
                [
515
                    's' => $res['result']['rows'][3]['s'],
516
                    's type' => 'bnode',
517
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest',
518
                    'p type' => 'uri',
519
                    'o' => $res['result']['rows'][3]['o'],
520
                    'o type' => 'bnode',
521
                ],
522
                [
523
                    's' => $res['result']['rows'][4]['s'],
524
                    's type' => 'bnode',
525
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first',
526
                    'p type' => 'uri',
527
                    'o' => '3',
528
                    'o type' => 'literal',
529
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
530
                ],
531
                [
532
                    's' => $res['result']['rows'][5]['s'],
533
                    's type' => 'bnode',
534
                    'p' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest',
535
                    'p type' => 'uri',
536
                    'o' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil',
537
                    'o type' => 'uri',
538
                ],
539
            ],
540
            $res['result']['rows']
541
        );
542
    }
543
544
    public function testInsertIntoConstruct()
545
    {
546
        // test data
547
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> CONSTRUCT {
548
            <http://baz> <http://location> "Leipzig" .
549
            <http://baz2> <http://location> "Grimma" .
550
        }');
551
552
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
553
        $this->assertEquals(2, \count($res['result']['rows']));
554
    }
555
556
    public function testInsertIntoWhere()
557
    {
558
        // test data
559
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> CONSTRUCT {
560
            <http://baz> <http://location> "Leipzig" .
561
            <http://baz2> <http://location> "Grimma" .
562
        } WHERE {
563
            ?s <http://location> "Leipzig" .
564
        }');
565
566
        // we expect that 1 element gets added to the store, because of the WHERE clause.
567
        // but store added none.
568
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> {?s ?p ?o.}');
569
        $this->assertEquals(2, \count($res['result']['rows']));
570
571
        $this->markTestSkipped(
572
            'Store does not check the WHERE clause when inserting data.'
573
            .' Too many triples were added.'
574
            .\PHP_EOL
575
            .\PHP_EOL.'FYI: https://www.w3.org/Submission/SPARQL-Update/#sec_examples and '
576
            .\PHP_EOL.'https://github.com/semsol/arc2/wiki/SPARQL-#insert-example'
577
        );
578
    }
579
580
    public function testInsertInto2GraphsSameTriples()
581
    {
582
        /*
583
         * Test behavior if same triple get inserted into two different graphs:
584
         * 1. add
585
         * 2. check additions
586
         * 3. delete graph2 content
587
         * 4. check again
588
         */
589
590
        $triple = '<http://foo> <http://location> "Leipzig" .';
591
        $this->subjectUnderTest->query('INSERT INTO <http://graph1/> {'.$triple.'}');
592
        $this->subjectUnderTest->query('INSERT INTO <http://graph2/> {'.$triple.'}');
593
594
        // check additions (graph1)
595
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph1/> {?s ?p ?o.}');
596
        $this->assertEquals(1, \count($res['result']['rows']));
597
598
        // check additions (graph2)
599
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph2/> {?s ?p ?o.}');
600
        $this->assertEquals(1, \count($res['result']['rows']));
601
602
        /*
603
         * test isolation by removing the triple from graph2
604
         */
605
        $this->subjectUnderTest->query('DELETE FROM <http://graph2/>');
606
607
        // check triples (graph1)
608
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph1/> {?s ?p ?o.}');
609
        $this->assertEquals(1, \count($res['result']['rows']));
610
611
        // check triples (graph2)
612
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph2/> {?s ?p ?o.}');
613
        $this->assertEquals(0, \count($res['result']['rows']));
614
    }
615
616
    /**
617
     * Tests old behavior of ARC2 store: its SQLite in-memory implementation was not able
618
     * to recognize all triples added by separate query calls.
619
     */
620
    public function testMultipleInsertsSameStore()
621
    {
622
        // add triples in separate query calls
623
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {<http://a> <http://b> <http://c> . }');
624
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {<http://a2> <http://b2> "c2"@de. }');
625
        $this->subjectUnderTest->query('INSERT INTO <http://ex/> {<http://a3> <http://b3> "c3"^^xsd:string . }');
626
627
        // check result
628
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> WHERE {?s ?p ?o.}');
629
630
        $this->assertEquals(3, \count($res['result']['rows']));
631
632
        $this->assertEquals(
633
            [
634
                [
635
                    's' => 'http://a',
636
                    's type' => 'uri',
637
                    'p' => 'http://b',
638
                    'p type' => 'uri',
639
                    'o' => 'http://c',
640
                    'o type' => 'uri',
641
                ],
642
                [
643
                    's' => 'http://a2',
644
                    's type' => 'uri',
645
                    'p' => 'http://b2',
646
                    'p type' => 'uri',
647
                    'o' => 'c2',
648
                    'o type' => 'literal',
649
                    'o lang' => 'de',
650
                ],
651
                [
652
                    's' => 'http://a3',
653
                    's type' => 'uri',
654
                    'p' => 'http://b3',
655
                    'p type' => 'uri',
656
                    'o' => 'c3',
657
                    'o type' => 'literal',
658
                    'o datatype' => 'http://www.w3.org/2001/XMLSchema#string',
659
                ],
660
            ],
661
            $res['result']['rows']
662
        );
663
    }
664
665
    public function testMultipleInsertQueriesInDifferentGraphs()
666
    {
667
        $this->subjectUnderTest->query('INSERT INTO <http://graph1/> {<http://foo/1> <http://foo/2> <http://foo/3> . }');
668
        $this->subjectUnderTest->query('INSERT INTO <http://graph2/> {<http://foo/4> <http://foo/5> <http://foo/6> . }');
669
        $this->subjectUnderTest->query('INSERT INTO <http://graph2/> {<http://foo/a> <http://foo/b> <http://foo/c> . }');
670
671
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph1/> WHERE {?s ?p ?o.}');
672
        $this->assertEquals(1, \count($res['result']['rows']));
673
674
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph2/> WHERE {?s ?p ?o.}');
675
        $this->assertEquals(2, \count($res['result']['rows']));
676
677
        $res = $this->subjectUnderTest->query('SELECT * WHERE {?s ?p ?o.}');
678
        $this->assertEquals(3, \count($res['result']['rows']));
679
    }
680
681
    public function testValueEscape()
682
    {
683
        $this->subjectUnderTest->query('INSERT INTO <http://graph1/> {<http://foo/1> <http://foo/2> \'"foobar";\' . }');
684
        $this->subjectUnderTest->query('INSERT INTO <http://graph1/> {<http://foo/1> <http://foo/2> "\'foobar2\'" . }');
685
686
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://graph1/> WHERE {?s ?p ?o.}');
687
        $this->assertEquals(2, \count($res['result']['rows']));
688
    }
689
690
    /**
691
     * Adds bulk of triples to test behavior.
692
     * May take at least one second to finish.
693
     */
694
    public function testAdditionOfManyTriples11()
695
    {
696
        $amount = 2000;
697
698
        // add triples in separate query calls
699
        for ($i = 0; $i < $amount; ++$i) {
700
            $this->subjectUnderTest->query('INSERT INTO <http://ex/> {
701
                <http://a> <http://b> <http://c'.$i.'> .
702
            }');
703
        }
704
705
        // check result
706
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://ex/> WHERE {?s ?p ?o.}');
707
708
        $this->assertEquals($amount, \count($res['result']['rows']));
709
    }
710
711
    /**
712
     */
713
    public function testInsertIntoMultipleTimes22()
714
    {
715
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
716
            _:b0  rdf:first  1 ;
717
                  rdf:rest   _:b1 .
718
            _:b1  rdf:first  ?x ;
719
                  rdf:rest   _:b2 .
720
            _:b2  rdf:first  3 ;
721
                  rdf:rest   rdf:nil .
722
        }');
723
724
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
725
            <http://a1> <http://b2> <http://c3> .
726
            <http://a4> <http://b5> <http://c6> .
727
        }');
728
729
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://example.com/> {?s ?p ?o.}');
730
731
        $this->assertCount(8, $res['result']['rows']);
732
    }
733
734
    /**
735
     * Calling addQuads lead to the following error in the past:
736
     *
737
     *      Integrity constraint violation: 19 UNIQUE constraint failed: id2val.id
738
     *
739
     * Because a max term ID was reset on each call of addQuads.
740
     */
741
    public function testInsertIntoIntegrityConstraintViolationId2Val()
742
    {
743
        $df = new DataFactory();
744
        $graph = 'http://g';
745
746
        $q1 = $df->quad(
747
            $df->namedNode('http://a'),
748
            $df->namedNode('http://b'),
749
            $df->namedNode('http://c'),
750
            $df->namedNode($graph)
751
        );
752
753
        // q2
754
        $q2 = $df->quad(
755
            $df->blankNode('123'),
756
            $df->namedNode('http://b'),
757
            $df->literal('foobar', 'de'),
758
            $df->namedNode($graph)
759
        );
760
761
        $this->subjectUnderTest->addQuads([$q1, $q2]);
762
        $this->subjectUnderTest->addQuads([$q1]); // re-add the same quad
763
764
        $res = $this->subjectUnderTest->query('SELECT * WHERE {?s ?p ?o.}');
765
766
        $this->assertCount(2, $res['result']['rows']);
767
    }
768
}
769