Failed Conditions
Pull Request — master (#7885)
by Šimon
09:02
created

QueryTest::testClone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

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