Passed
Pull Request — master (#7831)
by Peter
10:12
created

testIterateWithNoDistinctAndWrongSelectClause()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
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 testIterateWithNoDistinctAndManyAssociationSelectClause() : void
151
    {
152
        $q = $this->em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
153
        $q->iterate();
154
    }
155
156
    public function testIterateWithNoDistinctAndWithValidSelectClause() : void
157
    {
158
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
159
160
        self::assertInstanceOf(IterableResult::class, $q->iterate());
161
    }
162
163
    public function testIterateWithDistinct() : void
164
    {
165
        $q = $this->em->createQuery('SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
166
167
        self::assertInstanceOf(IterableResult::class, $q->iterate());
168
    }
169
170
    /**
171
     * @group DDC-1697
172
     */
173
    public function testCollectionParameters() : void
174
    {
175
        $cities = [
176
            0 => 'Paris',
177
            3 => 'Canne',
178
            9 => 'St Julien',
179
        ];
180
181
        $query = $this->em
182
                ->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)')
183
                ->setParameter('cities', $cities);
184
185
        $parameters = $query->getParameters();
186
        $parameter  = $parameters->first();
187
188
        self::assertEquals('cities', $parameter->getName());
189
        self::assertEquals($cities, $parameter->getValue());
190
    }
191
192
    /**
193
     * @group DDC-2224
194
     */
195
    public function testProcessParameterValueClassMetadata() : void
196
    {
197
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)');
198
        self::assertEquals(
199
            CmsAddress::class,
200
            $query->processParameterValue($this->em->getClassMetadata(CmsAddress::class))
201
        );
202
    }
203
204
    public function testProcessParameterValueObject() : void
205
    {
206
        $query    = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
207
        $user     = new CmsUser();
208
        $user->id = 12345;
209
210
        self::assertSame(
211
            12345,
212
            $query->processParameterValue($user)
213
        );
214
    }
215
216
    public function testProcessParameterValueNull() : void
217
    {
218
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
219
220
        self::assertNull($query->processParameterValue(null));
221
    }
222
223
    public function testDefaultQueryHints() : void
224
    {
225
        $config       = $this->em->getConfiguration();
226
        $defaultHints = [
227
            'hint_name_1' => 'hint_value_1',
228
            'hint_name_2' => 'hint_value_2',
229
            'hint_name_3' => 'hint_value_3',
230
        ];
231
232
        $config->setDefaultQueryHints($defaultHints);
233
        $query = $this->em->createQuery();
234
        self::assertSame($config->getDefaultQueryHints(), $query->getHints());
235
        $this->em->getConfiguration()->setDefaultQueryHint('hint_name_1', 'hint_another_value_1');
236
        self::assertNotSame($config->getDefaultQueryHints(), $query->getHints());
237
        $q2 = clone $query;
238
        self::assertSame($config->getDefaultQueryHints(), $q2->getHints());
239
    }
240
241
    /**
242
     * @group DDC-3714
243
     */
244
    public function testResultCacheCaching() : void
245
    {
246
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
247
        $this->em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
248
        /** @var DriverConnectionMock $driverConnectionMock */
249
        $driverConnectionMock = $this->em->getConnection()->getWrappedConnection();
250
        $stmt                 = new StatementArrayMock([
251
            ['c0' => 1],
252
        ]);
253
        $driverConnectionMock->setStatementMock($stmt);
254
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
255
            ->useQueryCache(true)
256
            ->useResultCache(true, 60)
257
            //let it cache
258
            ->getResult();
259
260
        self::assertCount(1, $res);
261
262
        $driverConnectionMock->setStatementMock(null);
263
264
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
265
            ->useQueryCache(true)
266
            ->useResultCache(false)
267
            ->getResult();
268
        self::assertCount(0, $res);
269
    }
270
271
    /**
272
     * @group DDC-3741
273
     */
274
    public function testSetHydrationCacheProfileNull() : void
275
    {
276
        $query = $this->em->createQuery();
277
        $query->setHydrationCacheProfile(null);
278
279
        self::assertNull($query->getHydrationCacheProfile());
280
    }
281
282
    /**
283
     * @group 2947
284
     */
285
    public function testResultCacheEviction() : void
286
    {
287
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
288
289
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
290
                          ->useResultCache(true);
291
292
        /** @var DriverConnectionMock $driverConnectionMock */
293
        $driverConnectionMock = $this->em->getConnection()
294
            ->getWrappedConnection();
295
296
        // Performs the query and sets up the initial cache
297
        self::assertCount(0, $query->getResult());
298
299
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
300
301
        // Performs the query and sets up the initial cache
302
        self::assertCount(1, $query->expireResultCache(true)->getResult());
303
304
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1], ['c0' => 2]]));
305
306
        // Retrieves cached data since expire flag is false and we have a cached result set
307
        self::assertCount(1, $query->expireResultCache(false)->getResult());
308
309
        // Performs the query and caches the result set since expire flag is true
310
        self::assertCount(2, $query->expireResultCache(true)->getResult());
311
312
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
313
314
        // Retrieves cached data since expire flag is false and we have a cached result set
315
        self::assertCount(2, $query->expireResultCache(false)->getResult());
316
    }
317
318
    /**
319
     * @group #6162
320
     */
321
    public function testSelectJoinSubquery() : void
322
    {
323
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u JOIN (SELECT )');
324
325
        $this->expectException(QueryException::class);
326
        $this->expectExceptionMessage('Subquery');
327
        $query->getSQL();
328
    }
329
330
    /**
331
     * @group #6162
332
     */
333
    public function testSelectFromSubquery() : void
334
    {
335
        $query = $this->em->createQuery('select u from (select Doctrine\Tests\Models\CMS\CmsUser c) as u');
336
337
        $this->expectException(QueryException::class);
338
        $this->expectExceptionMessage('Subquery');
339
        $query->getSQL();
340
    }
341
342
    /**
343
     * @group 6699
344
     */
345
    public function testGetParameterTypeJuggling() : void
346
    {
347
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0');
348
349
        $query->setParameter(0, 0);
350
351
        self::assertCount(1, $query->getParameters());
352
        self::assertSame(0, $query->getParameter(0)->getValue());
353
        self::assertSame(0, $query->getParameter('0')->getValue());
354
    }
355
356
    /**
357
     * @group 6699
358
     */
359
    public function testSetParameterWithNameZeroIsNotOverridden() : void
360
    {
361
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
362
363
        $query->setParameter(0, 0);
364
        $query->setParameter('name', 'Doctrine');
365
366
        self::assertCount(2, $query->getParameters());
367
        self::assertSame(0, $query->getParameter('0')->getValue());
368
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
369
    }
370
371
    /**
372
     * @group 6699
373
     */
374
    public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void
375
    {
376
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
377
378
        $query->setParameter('name', 'Doctrine');
379
        $query->setParameter(0, 0);
380
381
        self::assertCount(2, $query->getParameters());
382
        self::assertSame(0, $query->getParameter(0)->getValue());
383
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
384
    }
385
386
    /**
387
     * @group 6699
388
     */
389
    public function testSetParameterWithTypeJugglingWorks() : void
390
    {
391
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
392
393
        $query->setParameter('0', 1);
394
        $query->setParameter('name', 'Doctrine');
395
        $query->setParameter(0, 2);
396
        $query->setParameter('0', 3);
397
398
        self::assertCount(2, $query->getParameters());
399
        self::assertSame(3, $query->getParameter(0)->getValue());
400
        self::assertSame(3, $query->getParameter('0')->getValue());
401
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
402
    }
403
404
    /**
405
     * @group 6748
406
     */
407
    public function testResultCacheProfileCanBeRemovedViaSetter() : void
408
    {
409
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
410
411
        $query = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u');
412
        $query->useResultCache(true);
413
        $query->setResultCacheProfile();
414
415
        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

415
        /** @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...
416
    }
417
418
    /** @group 7527 */
419
    public function testValuesAreNotBeingResolvedForSpecifiedParameterTypes() : void
420
    {
421
        $unitOfWork = $this->createMock(UnitOfWork::class);
422
423
        $this->em->setUnitOfWork($unitOfWork);
424
425
        $unitOfWork
426
            ->expects(self::never())
427
            ->method('getSingleIdentifierValue');
428
429
        $query = $this->em->createQuery('SELECT d FROM ' . DateTimeModel::class . ' d WHERE d.datetime = :value');
430
431
        $query->setParameter('value', new DateTime(), Type::DATETIME);
432
433
        self::assertEmpty($query->getResult());
434
    }
435
}
436