Passed
Pull Request — master (#8013)
by Roman
09:42 queued 49s
created

QueryTest::testSetParametersWithInvalidSignature()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 11
rs 10
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 testSetParametersWithInvalidSignature() : void
68
    {
69
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
70
71
        $parameters = new ArrayCollection(['key' => 'value']);
72
73
        $query->setParameters($parameters);
74
75
        $this->expectException(QueryException::class);
76
        $this->expectExceptionMessage('Set parameter must be instance of \Doctrine\ORM\Query\Parameter');
77
        $query->getSQL();
78
    }
79
80
    public function testFree() : void
81
    {
82
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
83
        $query->setParameter(2, 84, ParameterType::INTEGER);
84
85
        $query->free();
86
87
        self::assertCount(0, $query->getParameters());
88
    }
89
90
    public function testClone() : void
91
    {
92
        $dql = 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1';
93
94
        $query = $this->em->createQuery($dql);
95
        $query->setParameter(2, 84, ParameterType::INTEGER);
96
        $query->setHint('foo', 'bar');
97
98
        $cloned = clone $query;
99
100
        self::assertEquals($dql, $cloned->getDQL());
101
        self::assertCount(0, $cloned->getParameters());
102
        self::assertFalse($cloned->getHint('foo'));
103
    }
104
105
    public function testFluentQueryInterface() : void
106
    {
107
        $q  = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
108
        $q2 = $q->expireQueryCache(true)
109
          ->setQueryCacheLifetime(3600)
110
          ->setQueryCacheDriver(null)
111
          ->expireResultCache(true)
112
          ->setHint('foo', 'bar')
113
          ->setHint('bar', 'baz')
114
          ->setParameter(1, 'bar')
115
          ->setParameters(new ArrayCollection([new Parameter(2, 'baz')]))
116
          ->setResultCacheDriver(null)
117
          ->setResultCacheId('foo')
118
          ->setDQL('foo')
119
          ->setFirstResult(10)
120
          ->setMaxResults(10);
121
122
        self::assertSame($q2, $q);
123
    }
124
125
    /**
126
     * @group DDC-968
127
     */
128
    public function testHints() : void
129
    {
130
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
131
        $q->setHint('foo', 'bar')->setHint('bar', 'baz');
132
133
        self::assertEquals('bar', $q->getHint('foo'));
134
        self::assertEquals('baz', $q->getHint('bar'));
135
        self::assertEquals(['foo' => 'bar', 'bar' => 'baz'], $q->getHints());
136
        self::assertTrue($q->hasHint('foo'));
137
        self::assertFalse($q->hasHint('barFooBaz'));
138
    }
139
140
    /**
141
     * @group DDC-1588
142
     */
143
    public function testQueryDefaultResultCache() : void
144
    {
145
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
146
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
147
        $q->useResultCache(true);
148
        self::assertSame($this->em->getConfiguration()->getResultCacheImpl(), $q->getQueryCacheProfile()->getResultCacheDriver());
149
    }
150
151
    /**
152
     * @expectedException Doctrine\ORM\Query\QueryException
153
     */
154
    public function testIterateWithNoDistinctAndWrongSelectClause() : void
155
    {
156
        $q = $this->em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
157
        $q->iterate();
158
    }
159
160
    /**
161
     * @expectedException Doctrine\ORM\Query\QueryException
162
     */
163
    public function testIterateWithNoDistinctAndWithValidSelectClause() : void
164
    {
165
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
166
        $q->iterate();
167
    }
168
169
    public function testIterateWithDistinct() : void
170
    {
171
        $q = $this->em->createQuery('SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
172
173
        self::assertInstanceOf(IterableResult::class, $q->iterate());
174
    }
175
176
    /**
177
     * @group DDC-1697
178
     */
179
    public function testCollectionParameters() : void
180
    {
181
        $cities = [
182
            0 => 'Paris',
183
            3 => 'Canne',
184
            9 => 'St Julien',
185
        ];
186
187
        $query = $this->em
188
                ->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)')
189
                ->setParameter('cities', $cities);
190
191
        $parameters = $query->getParameters();
192
        $parameter  = $parameters->first();
193
194
        self::assertEquals('cities', $parameter->getName());
195
        self::assertEquals($cities, $parameter->getValue());
196
    }
197
198
    /**
199
     * @group DDC-2224
200
     */
201
    public function testProcessParameterValueClassMetadata() : void
202
    {
203
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)');
204
        self::assertEquals(
205
            CmsAddress::class,
206
            $query->processParameterValue($this->em->getClassMetadata(CmsAddress::class))
207
        );
208
    }
209
210
    public function testProcessParameterValueObject() : void
211
    {
212
        $query    = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
213
        $user     = new CmsUser();
214
        $user->id = 12345;
215
216
        self::assertSame(
217
            12345,
218
            $query->processParameterValue($user)
219
        );
220
    }
221
222
    public function testProcessParameterValueNull() : void
223
    {
224
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
225
226
        self::assertNull($query->processParameterValue(null));
227
    }
228
229
    public function testDefaultQueryHints() : void
230
    {
231
        $config       = $this->em->getConfiguration();
232
        $defaultHints = [
233
            'hint_name_1' => 'hint_value_1',
234
            'hint_name_2' => 'hint_value_2',
235
            'hint_name_3' => 'hint_value_3',
236
        ];
237
238
        $config->setDefaultQueryHints($defaultHints);
239
        $query = $this->em->createQuery();
240
        self::assertSame($config->getDefaultQueryHints(), $query->getHints());
241
        $this->em->getConfiguration()->setDefaultQueryHint('hint_name_1', 'hint_another_value_1');
242
        self::assertNotSame($config->getDefaultQueryHints(), $query->getHints());
243
        $q2 = clone $query;
244
        self::assertSame($config->getDefaultQueryHints(), $q2->getHints());
245
    }
246
247
    /**
248
     * @group DDC-3714
249
     */
250
    public function testResultCacheCaching() : void
251
    {
252
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
253
        $this->em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
254
        /** @var DriverConnectionMock $driverConnectionMock */
255
        $driverConnectionMock = $this->em->getConnection()->getWrappedConnection();
256
        $stmt                 = new StatementArrayMock([
257
            ['c0' => 1],
258
        ]);
259
        $driverConnectionMock->setStatementMock($stmt);
260
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
261
            ->useQueryCache(true)
262
            ->useResultCache(true, 60)
263
            //let it cache
264
            ->getResult();
265
266
        self::assertCount(1, $res);
267
268
        $driverConnectionMock->setStatementMock(null);
269
270
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
271
            ->useQueryCache(true)
272
            ->useResultCache(false)
273
            ->getResult();
274
        self::assertCount(0, $res);
275
    }
276
277
    /**
278
     * @group DDC-3741
279
     */
280
    public function testSetHydrationCacheProfileNull() : void
281
    {
282
        $query = $this->em->createQuery();
283
        $query->setHydrationCacheProfile(null);
284
285
        self::assertNull($query->getHydrationCacheProfile());
286
    }
287
288
    /**
289
     * @group 2947
290
     */
291
    public function testResultCacheEviction() : void
292
    {
293
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
294
295
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
296
                          ->useResultCache(true);
297
298
        /** @var DriverConnectionMock $driverConnectionMock */
299
        $driverConnectionMock = $this->em->getConnection()
300
            ->getWrappedConnection();
301
302
        // Performs the query and sets up the initial cache
303
        self::assertCount(0, $query->getResult());
304
305
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
306
307
        // Performs the query and sets up the initial cache
308
        self::assertCount(1, $query->expireResultCache(true)->getResult());
309
310
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1], ['c0' => 2]]));
311
312
        // Retrieves cached data since expire flag is false and we have a cached result set
313
        self::assertCount(1, $query->expireResultCache(false)->getResult());
314
315
        // Performs the query and caches the result set since expire flag is true
316
        self::assertCount(2, $query->expireResultCache(true)->getResult());
317
318
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
319
320
        // Retrieves cached data since expire flag is false and we have a cached result set
321
        self::assertCount(2, $query->expireResultCache(false)->getResult());
322
    }
323
324
    /**
325
     * @group #6162
326
     */
327
    public function testSelectJoinSubquery() : void
328
    {
329
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u JOIN (SELECT )');
330
331
        $this->expectException(QueryException::class);
332
        $this->expectExceptionMessage('Subquery');
333
        $query->getSQL();
334
    }
335
336
    /**
337
     * @group #6162
338
     */
339
    public function testSelectFromSubquery() : void
340
    {
341
        $query = $this->em->createQuery('select u from (select Doctrine\Tests\Models\CMS\CmsUser c) as u');
342
343
        $this->expectException(QueryException::class);
344
        $this->expectExceptionMessage('Subquery');
345
        $query->getSQL();
346
    }
347
348
    /**
349
     * @group 6699
350
     */
351
    public function testGetParameterTypeJuggling() : void
352
    {
353
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0');
354
355
        $query->setParameter(0, 0);
356
357
        self::assertCount(1, $query->getParameters());
358
        self::assertSame(0, $query->getParameter(0)->getValue());
359
        self::assertSame(0, $query->getParameter('0')->getValue());
360
    }
361
362
    /**
363
     * @group 6699
364
     */
365
    public function testSetParameterWithNameZeroIsNotOverridden() : void
366
    {
367
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
368
369
        $query->setParameter(0, 0);
370
        $query->setParameter('name', 'Doctrine');
371
372
        self::assertCount(2, $query->getParameters());
373
        self::assertSame(0, $query->getParameter('0')->getValue());
374
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
375
    }
376
377
    /**
378
     * @group 6699
379
     */
380
    public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void
381
    {
382
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
383
384
        $query->setParameter('name', 'Doctrine');
385
        $query->setParameter(0, 0);
386
387
        self::assertCount(2, $query->getParameters());
388
        self::assertSame(0, $query->getParameter(0)->getValue());
389
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
390
    }
391
392
    /**
393
     * @group 6699
394
     */
395
    public function testSetParameterWithTypeJugglingWorks() : void
396
    {
397
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
398
399
        $query->setParameter('0', 1);
400
        $query->setParameter('name', 'Doctrine');
401
        $query->setParameter(0, 2);
402
        $query->setParameter('0', 3);
403
404
        self::assertCount(2, $query->getParameters());
405
        self::assertSame(3, $query->getParameter(0)->getValue());
406
        self::assertSame(3, $query->getParameter('0')->getValue());
407
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
408
    }
409
410
    /**
411
     * @group 6748
412
     */
413
    public function testResultCacheProfileCanBeRemovedViaSetter() : void
414
    {
415
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
416
417
        $query = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u');
418
        $query->useResultCache(true);
419
        $query->setResultCacheProfile();
420
421
        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

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