QueryTest   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 403
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 176
c 3
b 0
f 0
dl 0
loc 403
rs 10
wmc 28

28 Methods

Rating   Name   Duplication   Size   Complexity  
A testFree() 0 8 1
A testGetParameters() 0 7 1
A testGetParametersHasSomeAlready() 0 9 1
A testSetParameterWithTypeJugglingWorks() 0 13 1
A testCollectionParameters() 0 17 1
A testValuesAreNotBeingResolvedForSpecifiedParameterTypes() 0 15 1
A testClone() 0 13 1
A testSetParameters() 0 11 1
A testSetHydrationCacheProfileNull() 0 6 1
A testFluentQueryInterface() 0 18 1
A testResultCacheCaching() 0 25 1
A setUp() 0 3 1
A testGetParameterTypeJuggling() 0 9 1
A testIterateWithDistinct() 0 5 1
A testIterateWithNoDistinctAndWithValidSelectClause() 0 4 1
A testResultCacheProfileCanBeRemovedViaSetter() 0 9 1
A testProcessParameterValueClassMetadata() 0 6 1
A testHints() 0 10 1
A testSelectJoinSubquery() 0 7 1
A testDefaultQueryHints() 0 16 1
A testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() 0 10 1
A testQueryDefaultResultCache() 0 6 1
A testSetParameterWithNameZeroIsNotOverridden() 0 10 1
A testSelectFromSubquery() 0 7 1
A testResultCacheEviction() 0 31 1
A testIterateWithNoDistinctAndWrongSelectClause() 0 4 1
A testProcessParameterValueObject() 0 9 1
A testProcessParameterValueNull() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Query;
6
7
use DateTime;
8
use Doctrine\Common\Cache\ArrayCache;
9
use Doctrine\Common\Collections\ArrayCollection;
10
use Doctrine\DBAL\ParameterType;
11
use Doctrine\DBAL\Types\Type;
12
use Doctrine\ORM\Internal\Hydration\IterableResult;
13
use Doctrine\ORM\Query\Parameter;
14
use Doctrine\ORM\Query\QueryException;
15
use Doctrine\ORM\UnitOfWork;
16
use Doctrine\Tests\Mocks\DriverConnectionMock;
17
use Doctrine\Tests\Mocks\EntityManagerMock;
18
use Doctrine\Tests\Mocks\StatementArrayMock;
19
use Doctrine\Tests\Models\CMS\CmsAddress;
20
use Doctrine\Tests\Models\CMS\CmsUser;
21
use Doctrine\Tests\Models\Generic\DateTimeModel;
22
use Doctrine\Tests\OrmTestCase;
23
24
class QueryTest extends OrmTestCase
25
{
26
    /** @var EntityManagerMock */
27
    protected $em;
28
29
    protected function setUp() : void
30
    {
31
        $this->em = $this->getTestEntityManager();
32
    }
33
34
    public function testGetParameters() : void
35
    {
36
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
37
38
        $parameters = new ArrayCollection();
39
40
        self::assertEquals($parameters, $query->getParameters());
41
    }
42
43
    public function testGetParametersHasSomeAlready() : void
44
    {
45
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
46
        $query->setParameter(2, 84);
47
48
        $parameters = new ArrayCollection();
49
        $parameters->add(new Parameter(2, 84));
50
51
        self::assertEquals($parameters, $query->getParameters());
52
    }
53
54
    public function testSetParameters() : void
55
    {
56
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
57
58
        $parameters = new ArrayCollection();
59
        $parameters->add(new Parameter(1, 'foo'));
60
        $parameters->add(new Parameter(2, 'bar'));
61
62
        $query->setParameters($parameters);
63
64
        self::assertEquals($parameters, $query->getParameters());
65
    }
66
67
    public function testFree() : void
68
    {
69
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
70
        $query->setParameter(2, 84, ParameterType::INTEGER);
71
72
        $query->free();
73
74
        self::assertCount(0, $query->getParameters());
75
    }
76
77
    public function testClone() : void
78
    {
79
        $dql = 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1';
80
81
        $query = $this->em->createQuery($dql);
82
        $query->setParameter(2, 84, ParameterType::INTEGER);
83
        $query->setHint('foo', 'bar');
84
85
        $cloned = clone $query;
86
87
        self::assertEquals($dql, $cloned->getDQL());
88
        self::assertCount(0, $cloned->getParameters());
89
        self::assertFalse($cloned->getHint('foo'));
90
    }
91
92
    public function testFluentQueryInterface() : void
93
    {
94
        $q  = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
95
        $q2 = $q->expireQueryCache(true)
96
          ->setQueryCacheLifetime(3600)
97
          ->setQueryCacheDriver(null)
98
          ->expireResultCache(true)
99
          ->setHint('foo', 'bar')
100
          ->setHint('bar', 'baz')
101
          ->setParameter(1, 'bar')
102
          ->setParameters(new ArrayCollection([new Parameter(2, 'baz')]))
103
          ->setResultCacheDriver(null)
104
          ->setResultCacheId('foo')
105
          ->setDQL('foo')
106
          ->setFirstResult(10)
107
          ->setMaxResults(10);
108
109
        self::assertSame($q2, $q);
110
    }
111
112
    /**
113
     * @group DDC-968
114
     */
115
    public function testHints() : void
116
    {
117
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
118
        $q->setHint('foo', 'bar')->setHint('bar', 'baz');
119
120
        self::assertEquals('bar', $q->getHint('foo'));
121
        self::assertEquals('baz', $q->getHint('bar'));
122
        self::assertEquals(['foo' => 'bar', 'bar' => 'baz'], $q->getHints());
123
        self::assertTrue($q->hasHint('foo'));
124
        self::assertFalse($q->hasHint('barFooBaz'));
125
    }
126
127
    /**
128
     * @group DDC-1588
129
     */
130
    public function testQueryDefaultResultCache() : void
131
    {
132
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
133
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
134
        $q->useResultCache(true);
135
        self::assertSame($this->em->getConfiguration()->getResultCacheImpl(), $q->getQueryCacheProfile()->getResultCacheDriver());
136
    }
137
138
    /**
139
     * @expectedException Doctrine\ORM\Query\QueryException
140
     */
141
    public function testIterateWithNoDistinctAndWrongSelectClause() : void
142
    {
143
        $q = $this->em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
144
        $q->iterate();
145
    }
146
147
    /**
148
     * @expectedException Doctrine\ORM\Query\QueryException
149
     */
150
    public function testIterateWithNoDistinctAndWithValidSelectClause() : void
151
    {
152
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
153
        $q->iterate();
154
    }
155
156
    public function testIterateWithDistinct() : void
157
    {
158
        $q = $this->em->createQuery('SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
159
160
        self::assertInstanceOf(IterableResult::class, $q->iterate());
161
    }
162
163
    /**
164
     * @group DDC-1697
165
     */
166
    public function testCollectionParameters() : void
167
    {
168
        $cities = [
169
            0 => 'Paris',
170
            3 => 'Canne',
171
            9 => 'St Julien',
172
        ];
173
174
        $query = $this->em
175
                ->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)')
176
                ->setParameter('cities', $cities);
177
178
        $parameters = $query->getParameters();
179
        $parameter  = $parameters->first();
180
181
        self::assertEquals('cities', $parameter->getName());
182
        self::assertEquals($cities, $parameter->getValue());
183
    }
184
185
    /**
186
     * @group DDC-2224
187
     */
188
    public function testProcessParameterValueClassMetadata() : void
189
    {
190
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)');
191
        self::assertEquals(
192
            CmsAddress::class,
193
            $query->processParameterValue($this->em->getClassMetadata(CmsAddress::class))
194
        );
195
    }
196
197
    public function testProcessParameterValueObject() : void
198
    {
199
        $query    = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
200
        $user     = new CmsUser();
201
        $user->id = 12345;
202
203
        self::assertSame(
204
            12345,
205
            $query->processParameterValue($user)
206
        );
207
    }
208
209
    public function testProcessParameterValueNull() : void
210
    {
211
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
212
213
        self::assertNull($query->processParameterValue(null));
214
    }
215
216
    public function testDefaultQueryHints() : void
217
    {
218
        $config       = $this->em->getConfiguration();
219
        $defaultHints = [
220
            'hint_name_1' => 'hint_value_1',
221
            'hint_name_2' => 'hint_value_2',
222
            'hint_name_3' => 'hint_value_3',
223
        ];
224
225
        $config->setDefaultQueryHints($defaultHints);
226
        $query = $this->em->createQuery();
227
        self::assertSame($config->getDefaultQueryHints(), $query->getHints());
228
        $this->em->getConfiguration()->setDefaultQueryHint('hint_name_1', 'hint_another_value_1');
229
        self::assertNotSame($config->getDefaultQueryHints(), $query->getHints());
230
        $q2 = clone $query;
231
        self::assertSame($config->getDefaultQueryHints(), $q2->getHints());
232
    }
233
234
    /**
235
     * @group DDC-3714
236
     */
237
    public function testResultCacheCaching() : void
238
    {
239
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
240
        $this->em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
241
        /** @var DriverConnectionMock $driverConnectionMock */
242
        $driverConnectionMock = $this->em->getConnection()->getWrappedConnection();
243
        $stmt                 = new StatementArrayMock([
244
            ['c0' => 1],
245
        ]);
246
        $driverConnectionMock->setStatementMock($stmt);
247
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
248
            ->useQueryCache(true)
249
            ->useResultCache(true, 60)
250
            //let it cache
251
            ->getResult();
252
253
        self::assertCount(1, $res);
254
255
        $driverConnectionMock->setStatementMock(null);
256
257
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
258
            ->useQueryCache(true)
259
            ->useResultCache(false)
260
            ->getResult();
261
        self::assertCount(0, $res);
262
    }
263
264
    /**
265
     * @group DDC-3741
266
     */
267
    public function testSetHydrationCacheProfileNull() : void
268
    {
269
        $query = $this->em->createQuery();
270
        $query->setHydrationCacheProfile(null);
271
272
        self::assertNull($query->getHydrationCacheProfile());
273
    }
274
275
    /**
276
     * @group 2947
277
     */
278
    public function testResultCacheEviction() : void
279
    {
280
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
281
282
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
283
                          ->useResultCache(true);
284
285
        /** @var DriverConnectionMock $driverConnectionMock */
286
        $driverConnectionMock = $this->em->getConnection()
287
            ->getWrappedConnection();
288
289
        // Performs the query and sets up the initial cache
290
        self::assertCount(0, $query->getResult());
291
292
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
293
294
        // Performs the query and sets up the initial cache
295
        self::assertCount(1, $query->expireResultCache(true)->getResult());
296
297
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1], ['c0' => 2]]));
298
299
        // Retrieves cached data since expire flag is false and we have a cached result set
300
        self::assertCount(1, $query->expireResultCache(false)->getResult());
301
302
        // Performs the query and caches the result set since expire flag is true
303
        self::assertCount(2, $query->expireResultCache(true)->getResult());
304
305
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
306
307
        // Retrieves cached data since expire flag is false and we have a cached result set
308
        self::assertCount(2, $query->expireResultCache(false)->getResult());
309
    }
310
311
    /**
312
     * @group #6162
313
     */
314
    public function testSelectJoinSubquery() : void
315
    {
316
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u JOIN (SELECT )');
317
318
        $this->expectException(QueryException::class);
319
        $this->expectExceptionMessage('Subquery');
320
        $query->getSQL();
321
    }
322
323
    /**
324
     * @group #6162
325
     */
326
    public function testSelectFromSubquery() : void
327
    {
328
        $query = $this->em->createQuery('select u from (select Doctrine\Tests\Models\CMS\CmsUser c) as u');
329
330
        $this->expectException(QueryException::class);
331
        $this->expectExceptionMessage('Subquery');
332
        $query->getSQL();
333
    }
334
335
    /**
336
     * @group 6699
337
     */
338
    public function testGetParameterTypeJuggling() : void
339
    {
340
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0');
341
342
        $query->setParameter(0, 0);
343
344
        self::assertCount(1, $query->getParameters());
345
        self::assertSame(0, $query->getParameter(0)->getValue());
346
        self::assertSame(0, $query->getParameter('0')->getValue());
347
    }
348
349
    /**
350
     * @group 6699
351
     */
352
    public function testSetParameterWithNameZeroIsNotOverridden() : void
353
    {
354
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
355
356
        $query->setParameter(0, 0);
357
        $query->setParameter('name', 'Doctrine');
358
359
        self::assertCount(2, $query->getParameters());
360
        self::assertSame(0, $query->getParameter('0')->getValue());
361
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
362
    }
363
364
    /**
365
     * @group 6699
366
     */
367
    public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void
368
    {
369
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
370
371
        $query->setParameter('name', 'Doctrine');
372
        $query->setParameter(0, 0);
373
374
        self::assertCount(2, $query->getParameters());
375
        self::assertSame(0, $query->getParameter(0)->getValue());
376
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
377
    }
378
379
    /**
380
     * @group 6699
381
     */
382
    public function testSetParameterWithTypeJugglingWorks() : void
383
    {
384
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
385
386
        $query->setParameter('0', 1);
387
        $query->setParameter('name', 'Doctrine');
388
        $query->setParameter(0, 2);
389
        $query->setParameter('0', 3);
390
391
        self::assertCount(2, $query->getParameters());
392
        self::assertSame(3, $query->getParameter(0)->getValue());
393
        self::assertSame(3, $query->getParameter('0')->getValue());
394
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
395
    }
396
397
    /**
398
     * @group 6748
399
     */
400
    public function testResultCacheProfileCanBeRemovedViaSetter() : void
401
    {
402
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
403
404
        $query = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u');
405
        $query->useResultCache(true);
406
        $query->setResultCacheProfile();
407
408
        self::assertAttributeSame(null, 'queryCacheProfile', $query);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertAttributeSame() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3338 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

408
        /** @scrutinizer ignore-deprecated */ self::assertAttributeSame(null, 'queryCacheProfile', $query);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
409
    }
410
411
    /** @group 7527 */
412
    public function testValuesAreNotBeingResolvedForSpecifiedParameterTypes() : void
413
    {
414
        $unitOfWork = $this->createMock(UnitOfWork::class);
415
416
        $this->em->setUnitOfWork($unitOfWork);
417
418
        $unitOfWork
419
            ->expects(self::never())
420
            ->method('getSingleIdentifierValue');
421
422
        $query = $this->em->createQuery('SELECT d FROM ' . DateTimeModel::class . ' d WHERE d.datetime = :value');
423
424
        $query->setParameter('value', new DateTime(), Type::DATETIME);
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Type::DATETIME has been deprecated: Use {@see Types::DATETIME_MUTABLE} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

424
        $query->setParameter('value', new DateTime(), /** @scrutinizer ignore-deprecated */ Type::DATETIME);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
425
426
        self::assertEmpty($query->getResult());
427
    }
428
}
429