Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SQLQueryTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SQLQueryTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class SQLQueryTest extends SapphireTest { |
||
8 | |||
9 | protected static $fixture_file = 'SQLQueryTest.yml'; |
||
10 | |||
11 | protected $extraDataObjects = array( |
||
12 | 'SQLQueryTest_DO', |
||
13 | 'SQLQueryTestBase', |
||
14 | 'SQLQueryTestChild' |
||
15 | ); |
||
16 | |||
17 | protected $oldDeprecation = null; |
||
18 | |||
19 | public function setUp() { |
||
23 | |||
24 | public function tearDown() { |
||
28 | |||
29 | public function testCount() { |
||
30 | |||
31 | //basic counting |
||
32 | $qry = SQLQueryTest_DO::get()->dataQuery()->getFinalisedQuery(); |
||
33 | $qry->setGroupBy('Common'); |
||
34 | $ids = $this->allFixtureIDs('SQLQueryTest_DO'); |
||
35 | $this->assertEquals(count($ids), $qry->count('"SQLQueryTest_DO"."ID"')); |
||
36 | |||
37 | //test with `having` |
||
38 | if (DB::get_conn() instanceof MySQLDatabase) { |
||
39 | $qry->setHaving('"Date" > 2012-02-01'); |
||
40 | $this->assertEquals(1, $qry->count('"SQLQueryTest_DO"."ID"')); |
||
41 | } |
||
42 | } |
||
43 | |||
44 | public function testEmptyQueryReturnsNothing() { |
||
48 | |||
49 | public function testSelectFromBasicTable() { |
||
50 | $query = new SQLQuery(); |
||
51 | $query->setFrom('MyTable'); |
||
52 | $this->assertSQLEquals("SELECT * FROM MyTable", $query->sql($parameters)); |
||
53 | $query->addFrom('MyJoin'); |
||
54 | $this->assertSQLEquals("SELECT * FROM MyTable MyJoin", $query->sql($parameters)); |
||
55 | } |
||
56 | |||
57 | public function testSelectFromUserSpecifiedFields() { |
||
58 | $query = new SQLQuery(); |
||
59 | $query->setSelect(array("Name", "Title", "Description")); |
||
60 | $query->setFrom("MyTable"); |
||
61 | $this->assertSQLEquals("SELECT Name, Title, Description FROM MyTable", $query->sql($parameters)); |
||
62 | } |
||
63 | |||
64 | public function testSelectWithWhereClauseFilter() { |
||
65 | $query = new SQLQuery(); |
||
66 | $query->setSelect(array("Name","Meta")); |
||
67 | $query->setFrom("MyTable"); |
||
68 | $query->setWhere("Name = 'Name'"); |
||
69 | $query->addWhere("Meta = 'Test'"); |
||
70 | $this->assertSQLEquals( |
||
71 | "SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')", |
||
72 | $query->sql($parameters) |
||
73 | ); |
||
74 | } |
||
75 | |||
76 | public function testSelectWithConstructorParameters() { |
||
77 | $query = new SQLQuery(array("Foo", "Bar"), "FooBarTable"); |
||
78 | $this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable", $query->sql($parameters)); |
||
79 | $query = new SQLQuery(array("Foo", "Bar"), "FooBarTable", array("Foo = 'Boo'")); |
||
80 | $this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable WHERE (Foo = 'Boo')", $query->sql($parameters)); |
||
81 | } |
||
82 | |||
83 | public function testSelectWithChainedMethods() { |
||
84 | $query = new SQLQuery(); |
||
85 | $query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'"); |
||
86 | $this->assertSQLEquals( |
||
87 | "SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test')", |
||
88 | $query->sql($parameters) |
||
89 | ); |
||
90 | } |
||
91 | |||
92 | View Code Duplication | public function testCanSortBy() { |
|
93 | $query = new SQLQuery(); |
||
94 | $query->setSelect("Name","Meta")->setFrom("MyTable")->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'"); |
||
95 | $this->assertTrue($query->canSortBy('Name ASC')); |
||
96 | $this->assertTrue($query->canSortBy('Name')); |
||
97 | } |
||
98 | |||
99 | View Code Duplication | public function testSelectWithChainedFilterParameters() { |
|
100 | $query = new SQLQuery(); |
||
101 | $query->setSelect(array("Name","Meta"))->setFrom("MyTable"); |
||
102 | $query->setWhere("Name = 'Name'")->addWhere("Meta = 'Test'")->addWhere("Beta != 'Gamma'"); |
||
103 | $this->assertSQLEquals( |
||
104 | "SELECT Name, Meta FROM MyTable WHERE (Name = 'Name') AND (Meta = 'Test') AND (Beta != 'Gamma')", |
||
105 | $query->sql($parameters) |
||
106 | ); |
||
107 | } |
||
108 | |||
109 | public function testSelectWithLimitClause() { |
||
126 | |||
127 | public function testSelectWithOrderbyClause() { |
||
128 | $query = new SQLQuery(); |
||
129 | $query->setFrom("MyTable"); |
||
130 | $query->setOrderBy('MyName'); |
||
131 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC', $query->sql($parameters)); |
||
132 | |||
133 | $query = new SQLQuery(); |
||
134 | $query->setFrom("MyTable"); |
||
135 | $query->setOrderBy('MyName desc'); |
||
136 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql($parameters)); |
||
137 | |||
138 | $query = new SQLQuery(); |
||
139 | $query->setFrom("MyTable"); |
||
140 | $query->setOrderBy('MyName ASC, Color DESC'); |
||
141 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color DESC', $query->sql($parameters)); |
||
142 | |||
143 | $query = new SQLQuery(); |
||
144 | $query->setFrom("MyTable"); |
||
145 | $query->setOrderBy('MyName ASC, Color'); |
||
146 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName ASC, Color ASC', $query->sql($parameters)); |
||
147 | |||
148 | $query = new SQLQuery(); |
||
149 | $query->setFrom("MyTable"); |
||
150 | $query->setOrderBy(array('MyName' => 'desc')); |
||
151 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC', $query->sql($parameters)); |
||
152 | |||
153 | $query = new SQLQuery(); |
||
154 | $query->setFrom("MyTable"); |
||
155 | $query->setOrderBy(array('MyName' => 'desc', 'Color')); |
||
156 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY MyName DESC, Color ASC', $query->sql($parameters)); |
||
157 | |||
158 | $query = new SQLQuery(); |
||
159 | $query->setFrom("MyTable"); |
||
160 | $query->setOrderBy('implode("MyName","Color")'); |
||
161 | $this->assertSQLEquals( |
||
162 | 'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC', |
||
163 | $query->sql($parameters)); |
||
164 | |||
165 | $query = new SQLQuery(); |
||
166 | $query->setFrom("MyTable"); |
||
167 | $query->setOrderBy('implode("MyName","Color") DESC'); |
||
168 | $this->assertSQLEquals( |
||
169 | 'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" DESC', |
||
170 | $query->sql($parameters)); |
||
171 | |||
172 | $query = new SQLQuery(); |
||
173 | $query->setFrom("MyTable"); |
||
174 | $query->setOrderBy('RAND()'); |
||
175 | $this->assertSQLEquals( |
||
176 | 'SELECT *, RAND() AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC', |
||
177 | $query->sql($parameters)); |
||
178 | |||
179 | $query = new SQLQuery(); |
||
180 | $query->setFrom("MyTable"); |
||
181 | $query->addFrom('INNER JOIN SecondTable USING (ID)'); |
||
182 | $query->addFrom('INNER JOIN ThirdTable USING (ID)'); |
||
183 | $query->setOrderBy('MyName'); |
||
184 | $this->assertSQLEquals( |
||
185 | 'SELECT * FROM MyTable ' |
||
186 | . 'INNER JOIN SecondTable USING (ID) ' |
||
187 | . 'INNER JOIN ThirdTable USING (ID) ' |
||
188 | . 'ORDER BY MyName ASC', |
||
189 | $query->sql($parameters)); |
||
190 | } |
||
191 | |||
192 | View Code Duplication | public function testNullLimit() { |
|
193 | $query = new SQLQuery(); |
||
194 | $query->setFrom("MyTable"); |
||
195 | $query->setLimit(null); |
||
196 | |||
197 | $this->assertSQLEquals( |
||
198 | 'SELECT * FROM MyTable', |
||
199 | $query->sql($parameters) |
||
200 | ); |
||
201 | } |
||
202 | |||
203 | View Code Duplication | public function testZeroLimit() { |
|
204 | $query = new SQLQuery(); |
||
205 | $query->setFrom("MyTable"); |
||
206 | $query->setLimit(0); |
||
207 | |||
208 | $this->assertSQLEquals( |
||
209 | 'SELECT * FROM MyTable', |
||
210 | $query->sql($parameters) |
||
211 | ); |
||
212 | } |
||
213 | |||
214 | public function testZeroLimitWithOffset() { |
||
229 | |||
230 | /** |
||
231 | * @expectedException InvalidArgumentException |
||
232 | */ |
||
233 | public function testNegativeLimit() { |
||
237 | |||
238 | /** |
||
239 | * @expectedException InvalidArgumentException |
||
240 | */ |
||
241 | public function testNegativeOffset() { |
||
245 | |||
246 | /** |
||
247 | * @expectedException InvalidArgumentException |
||
248 | */ |
||
249 | public function testNegativeOffsetAndLimit() { |
||
253 | |||
254 | public function testReverseOrderBy() { |
||
255 | $query = new SQLQuery(); |
||
256 | $query->setFrom('MyTable'); |
||
257 | |||
258 | // default is ASC |
||
259 | $query->setOrderBy("Name"); |
||
260 | $query->reverseOrderBy(); |
||
261 | |||
262 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql($parameters)); |
||
263 | |||
264 | $query->setOrderBy("Name DESC"); |
||
265 | $query->reverseOrderBy(); |
||
266 | |||
267 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name ASC',$query->sql($parameters)); |
||
268 | |||
269 | $query->setOrderBy(array("Name" => "ASC")); |
||
270 | $query->reverseOrderBy(); |
||
271 | |||
272 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name DESC',$query->sql($parameters)); |
||
273 | |||
274 | $query->setOrderBy(array("Name" => 'DESC', 'Color' => 'asc')); |
||
275 | $query->reverseOrderBy(); |
||
276 | |||
277 | $this->assertSQLEquals('SELECT * FROM MyTable ORDER BY Name ASC, Color DESC',$query->sql($parameters)); |
||
278 | |||
279 | $query->setOrderBy('implode("MyName","Color") DESC'); |
||
280 | $query->reverseOrderBy(); |
||
281 | |||
282 | $this->assertSQLEquals( |
||
283 | 'SELECT *, implode("MyName","Color") AS "_SortColumn0" FROM MyTable ORDER BY "_SortColumn0" ASC', |
||
284 | $query->sql($parameters)); |
||
285 | } |
||
286 | |||
287 | public function testFiltersOnID() { |
||
288 | $query = new SQLQuery(); |
||
289 | $query->setWhere("ID = 5"); |
||
290 | $this->assertTrue( |
||
291 | $query->filtersOnID(), |
||
292 | "filtersOnID() is true with simple unquoted column name" |
||
293 | ); |
||
294 | |||
295 | $query = new SQLQuery(); |
||
296 | $query->setWhere("ID=5"); |
||
297 | $this->assertTrue( |
||
298 | $query->filtersOnID(), |
||
299 | "filtersOnID() is true with simple unquoted column name and no spaces in equals sign" |
||
300 | ); |
||
301 | |||
302 | $query = new SQLQuery(); |
||
303 | $query->setWhere("Identifier = 5"); |
||
304 | $this->assertFalse( |
||
305 | $query->filtersOnID(), |
||
306 | "filtersOnID() is false with custom column name (starting with 'id')" |
||
307 | ); |
||
308 | |||
309 | $query = new SQLQuery(); |
||
310 | $query->setWhere("ParentID = 5"); |
||
311 | $this->assertFalse( |
||
312 | $query->filtersOnID(), |
||
313 | "filtersOnID() is false with column name ending in 'ID'" |
||
314 | ); |
||
315 | |||
316 | $query = new SQLQuery(); |
||
317 | $query->setWhere("MyTable.ID = 5"); |
||
318 | $this->assertTrue( |
||
319 | $query->filtersOnID(), |
||
320 | "filtersOnID() is true with table and column name" |
||
321 | ); |
||
322 | |||
323 | $query = new SQLQuery(); |
||
324 | $query->setWhere("MyTable.ID = 5"); |
||
325 | $this->assertTrue( |
||
326 | $query->filtersOnID(), |
||
327 | "filtersOnID() is true with table and quoted column name " |
||
328 | ); |
||
329 | } |
||
330 | |||
331 | public function testFiltersOnFK() { |
||
332 | $query = new SQLQuery(); |
||
333 | $query->setWhere("ID = 5"); |
||
334 | $this->assertFalse( |
||
335 | $query->filtersOnFK(), |
||
336 | "filtersOnFK() is true with simple unquoted column name" |
||
337 | ); |
||
338 | |||
339 | $query = new SQLQuery(); |
||
340 | $query->setWhere("Identifier = 5"); |
||
341 | $this->assertFalse( |
||
342 | $query->filtersOnFK(), |
||
343 | "filtersOnFK() is false with custom column name (starting with 'id')" |
||
344 | ); |
||
345 | |||
346 | $query = new SQLQuery(); |
||
347 | $query->setWhere("MyTable.ParentID = 5"); |
||
348 | $this->assertTrue( |
||
349 | $query->filtersOnFK(), |
||
350 | "filtersOnFK() is true with table and column name" |
||
351 | ); |
||
352 | |||
353 | $query = new SQLQuery(); |
||
354 | $query->setWhere("MyTable.`ParentID`= 5"); |
||
355 | $this->assertTrue( |
||
356 | $query->filtersOnFK(), |
||
357 | "filtersOnFK() is true with table and quoted column name " |
||
358 | ); |
||
359 | } |
||
360 | |||
361 | View Code Duplication | public function testInnerJoin() { |
|
362 | $query = new SQLQuery(); |
||
363 | $query->setFrom('MyTable'); |
||
364 | $query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2'); |
||
365 | $query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID'); |
||
366 | |||
367 | $this->assertSQLEquals('SELECT * FROM MyTable '. |
||
368 | 'INNER JOIN "MyOtherTable" ON MyOtherTable.ID = 2 '. |
||
369 | 'LEFT JOIN "MyLastTable" ON MyOtherTable.ID = MyLastTable.ID', |
||
370 | $query->sql($parameters) |
||
371 | ); |
||
372 | |||
373 | $query = new SQLQuery(); |
||
374 | $query->setFrom('MyTable'); |
||
375 | $query->addInnerJoin('MyOtherTable', 'MyOtherTable.ID = 2', 'table1'); |
||
376 | $query->addLeftJoin('MyLastTable', 'MyOtherTable.ID = MyLastTable.ID', 'table2'); |
||
377 | |||
378 | $this->assertSQLEquals('SELECT * FROM MyTable '. |
||
379 | 'INNER JOIN "MyOtherTable" AS "table1" ON MyOtherTable.ID = 2 '. |
||
380 | 'LEFT JOIN "MyLastTable" AS "table2" ON MyOtherTable.ID = MyLastTable.ID', |
||
381 | $query->sql($parameters) |
||
382 | ); |
||
383 | } |
||
384 | |||
385 | View Code Duplication | public function testJoinSubSelect() { |
|
386 | |||
387 | // Test sub-select works |
||
388 | $query = new SQLQuery(); |
||
389 | $query->setFrom('"MyTable"'); |
||
390 | $query->addInnerJoin('(SELECT * FROM "MyOtherTable")', |
||
391 | '"Mot"."MyTableID" = "MyTable"."ID"', 'Mot'); |
||
392 | $query->addLeftJoin('(SELECT "MyLastTable"."MyOtherTableID", COUNT(1) as "MyLastTableCount" ' |
||
393 | . 'FROM "MyLastTable" GROUP BY "MyOtherTableID")', |
||
394 | '"Mlt"."MyOtherTableID" = "Mot"."ID"', 'Mlt'); |
||
395 | $query->setOrderBy('COALESCE("Mlt"."MyLastTableCount", 0) DESC'); |
||
396 | |||
397 | $this->assertSQLEquals('SELECT *, COALESCE("Mlt"."MyLastTableCount", 0) AS "_SortColumn0" FROM "MyTable" '. |
||
398 | 'INNER JOIN (SELECT * FROM "MyOtherTable") AS "Mot" ON "Mot"."MyTableID" = "MyTable"."ID" ' . |
||
399 | 'LEFT JOIN (SELECT "MyLastTable"."MyOtherTableID", COUNT(1) as "MyLastTableCount" FROM "MyLastTable" ' |
||
400 | . 'GROUP BY "MyOtherTableID") AS "Mlt" ON "Mlt"."MyOtherTableID" = "Mot"."ID" ' . |
||
401 | 'ORDER BY "_SortColumn0" DESC', |
||
402 | $query->sql($parameters) |
||
403 | ); |
||
404 | |||
405 | // Test that table names do not get mistakenly identified as sub-selects |
||
406 | $query = new SQLQuery(); |
||
407 | $query->setFrom('"MyTable"'); |
||
408 | $query->addInnerJoin('NewsArticleSelected', '"News"."MyTableID" = "MyTable"."ID"', 'News'); |
||
409 | $this->assertSQLEquals( |
||
410 | 'SELECT * FROM "MyTable" INNER JOIN "NewsArticleSelected" AS "News" ON '. |
||
411 | '"News"."MyTableID" = "MyTable"."ID"', |
||
412 | $query->sql() |
||
413 | ); |
||
414 | |||
415 | } |
||
416 | |||
417 | public function testSetWhereAny() { |
||
418 | $query = new SQLQuery(); |
||
419 | $query->setFrom('MyTable'); |
||
420 | |||
421 | $query->setWhereAny(array( |
||
422 | 'Monkey' => 'Chimp', |
||
423 | 'Color' => 'Brown' |
||
424 | )); |
||
425 | $sql = $query->sql($parameters); |
||
426 | $this->assertSQLEquals("SELECT * FROM MyTable WHERE ((Monkey = ?) OR (Color = ?))", $sql); |
||
427 | $this->assertEquals(array('Chimp', 'Brown'), $parameters); |
||
428 | } |
||
429 | |||
430 | View Code Duplication | public function testSelectFirst() { |
|
431 | // Test first from sequence |
||
432 | $query = new SQLQuery(); |
||
433 | $query->setFrom('"SQLQueryTest_DO"'); |
||
434 | $query->setOrderBy('"Name"'); |
||
435 | $result = $query->firstRow()->execute(); |
||
436 | |||
437 | $records = array(); |
||
438 | foreach($result as $row) { |
||
439 | $records[] = $row; |
||
440 | } |
||
441 | |||
442 | $this->assertCount(1, $records); |
||
443 | $this->assertEquals('Object 1', $records[0]['Name']); |
||
444 | |||
445 | // Test first from empty sequence |
||
446 | $query = new SQLQuery(); |
||
447 | $query->setFrom('"SQLQueryTest_DO"'); |
||
448 | $query->setOrderBy('"Name"'); |
||
449 | $query->setWhere(array('"Name"' => 'Nonexistent Object')); |
||
450 | $result = $query->firstRow()->execute(); |
||
451 | |||
452 | $records = array(); |
||
453 | foreach($result as $row) { |
||
454 | $records[] = $row; |
||
455 | } |
||
456 | |||
457 | $this->assertCount(0, $records); |
||
458 | |||
459 | // Test that given the last item, the 'first' in this list matches the last |
||
460 | $query = new SQLQuery(); |
||
461 | $query->setFrom('"SQLQueryTest_DO"'); |
||
462 | $query->setOrderBy('"Name"'); |
||
463 | $query->setLimit(1, 1); |
||
464 | $result = $query->firstRow()->execute(); |
||
465 | |||
466 | $records = array(); |
||
467 | foreach($result as $row) { |
||
468 | $records[] = $row; |
||
469 | } |
||
470 | |||
471 | $this->assertCount(1, $records); |
||
472 | $this->assertEquals('Object 2', $records[0]['Name']); |
||
473 | } |
||
474 | |||
475 | View Code Duplication | public function testSelectLast() { |
|
476 | // Test last in sequence |
||
477 | $query = new SQLQuery(); |
||
478 | $query->setFrom('"SQLQueryTest_DO"'); |
||
479 | $query->setOrderBy('"Name"'); |
||
480 | $result = $query->lastRow()->execute(); |
||
481 | |||
482 | $records = array(); |
||
483 | foreach($result as $row) { |
||
484 | $records[] = $row; |
||
485 | } |
||
486 | |||
487 | $this->assertCount(1, $records); |
||
488 | $this->assertEquals('Object 2', $records[0]['Name']); |
||
489 | |||
490 | // Test last from empty sequence |
||
491 | $query = new SQLQuery(); |
||
492 | $query->setFrom('"SQLQueryTest_DO"'); |
||
493 | $query->setOrderBy('"Name"'); |
||
494 | $query->setWhere(array("\"Name\" = 'Nonexistent Object'")); |
||
495 | $result = $query->lastRow()->execute(); |
||
496 | |||
497 | $records = array(); |
||
498 | foreach($result as $row) { |
||
499 | $records[] = $row; |
||
500 | } |
||
501 | |||
502 | $this->assertCount(0, $records); |
||
503 | |||
504 | // Test that given the first item, the 'last' in this list matches the first |
||
505 | $query = new SQLQuery(); |
||
506 | $query->setFrom('"SQLQueryTest_DO"'); |
||
507 | $query->setOrderBy('"Name"'); |
||
508 | $query->setLimit(1); |
||
509 | $result = $query->lastRow()->execute(); |
||
510 | |||
511 | $records = array(); |
||
512 | foreach($result as $row) { |
||
513 | $records[] = $row; |
||
514 | } |
||
515 | |||
516 | $this->assertCount(1, $records); |
||
517 | $this->assertEquals('Object 1', $records[0]['Name']); |
||
518 | } |
||
519 | |||
520 | /** |
||
521 | * Tests aggregate() function |
||
522 | */ |
||
523 | public function testAggregate() { |
||
524 | $query = new SQLQuery('"Common"'); |
||
525 | $query->setFrom('"SQLQueryTest_DO"'); |
||
526 | $query->setGroupBy('"Common"'); |
||
527 | |||
528 | $queryClone = $query->aggregate('COUNT(*)', 'cnt'); |
||
529 | $result = $queryClone->execute(); |
||
530 | $this->assertEquals(array(2), $result->column('cnt')); |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * Tests that an ORDER BY is only added if a LIMIT is set. |
||
535 | */ |
||
536 | public function testAggregateNoOrderByIfNoLimit() { |
||
537 | $query = new SQLQuery(); |
||
538 | $query->setFrom('"SQLQueryTest_DO"'); |
||
539 | $query->setOrderBy('Common'); |
||
540 | $query->setLimit(array()); |
||
541 | |||
542 | $aggregate = $query->aggregate('MAX("ID")'); |
||
543 | $limit = $aggregate->getLimit(); |
||
544 | $this->assertEquals(array(), $aggregate->getOrderBy()); |
||
545 | $this->assertEquals(array(), $limit); |
||
546 | |||
547 | $query = new SQLQuery(); |
||
548 | $query->setFrom('"SQLQueryTest_DO"'); |
||
549 | $query->setOrderBy('Common'); |
||
550 | $query->setLimit(2); |
||
551 | |||
552 | $aggregate = $query->aggregate('MAX("ID")'); |
||
553 | $limit = $aggregate->getLimit(); |
||
554 | $this->assertEquals(array('Common' => 'ASC'), $aggregate->getOrderBy()); |
||
555 | $this->assertEquals(array('start' => 0, 'limit' => 2), $limit); |
||
556 | } |
||
557 | |||
558 | /** |
||
559 | * Test that "_SortColumn0" is added for an aggregate in the ORDER BY |
||
560 | * clause, in combination with a LIMIT and GROUP BY clause. |
||
561 | * For some databases, like MSSQL, this is a complicated scenario |
||
562 | * because a subselect needs to be done to query paginated data. |
||
563 | */ |
||
564 | public function testOrderByContainingAggregateAndLimitOffset() { |
||
565 | $query = new SQLQuery(); |
||
566 | $query->setSelect(array('"Name"', '"Meta"')); |
||
567 | $query->setFrom('"SQLQueryTest_DO"'); |
||
568 | $query->setOrderBy(array('MAX("Date")')); |
||
569 | $query->setGroupBy(array('"Name"', '"Meta"')); |
||
570 | $query->setLimit('1', '1'); |
||
571 | |||
572 | $records = array(); |
||
573 | foreach($query->execute() as $record) { |
||
574 | $records[] = $record; |
||
575 | } |
||
576 | |||
577 | $this->assertCount(1, $records); |
||
578 | |||
579 | $this->assertEquals('Object 2', $records[0]['Name']); |
||
580 | $this->assertEquals('2012-05-01 09:00:00', $records['0']['_SortColumn0']); |
||
581 | } |
||
582 | |||
583 | /** |
||
584 | * Test that multiple order elements are maintained in the given order |
||
585 | */ |
||
586 | public function testOrderByMultiple() { |
||
587 | if(DB::get_conn() instanceof MySQLDatabase) { |
||
588 | $query = new SQLQuery(); |
||
589 | $query->setSelect(array('"Name"', '"Meta"')); |
||
590 | $query->setFrom('"SQLQueryTest_DO"'); |
||
591 | $query->setOrderBy(array('MID("Name", 8, 1) DESC', '"Name" ASC')); |
||
592 | |||
593 | $records = array(); |
||
594 | foreach($query->execute() as $record) { |
||
595 | $records[] = $record; |
||
596 | } |
||
597 | |||
598 | $this->assertCount(2, $records); |
||
599 | |||
600 | $this->assertEquals('Object 2', $records[0]['Name']); |
||
601 | $this->assertEquals('2', $records[0]['_SortColumn0']); |
||
602 | |||
603 | $this->assertEquals('Object 1', $records[1]['Name']); |
||
604 | $this->assertEquals('1', $records[1]['_SortColumn0']); |
||
605 | } |
||
606 | } |
||
607 | |||
608 | public function testSelect() { |
||
609 | $query = new SQLQuery('"Title"', '"MyTable"'); |
||
610 | $query->addSelect('"TestField"'); |
||
611 | $this->assertSQLEquals( |
||
612 | 'SELECT "Title", "TestField" FROM "MyTable"', |
||
613 | $query->sql() |
||
614 | ); |
||
615 | |||
616 | // Test replacement of select |
||
617 | $query->setSelect(array( |
||
618 | 'Field' => '"Field"', |
||
619 | 'AnotherAlias' => '"AnotherField"' |
||
620 | )); |
||
621 | $this->assertSQLEquals( |
||
622 | 'SELECT "Field", "AnotherField" AS "AnotherAlias" FROM "MyTable"', |
||
623 | $query->sql() |
||
624 | ); |
||
625 | |||
626 | // Check that ' as ' selects don't get mistaken as aliases |
||
627 | $query->addSelect(array( |
||
628 | 'Relevance' => "MATCH (Title, MenuTitle) AGAINST ('Two as One')" |
||
629 | )); |
||
630 | $this->assertSQLEquals( |
||
631 | 'SELECT "Field", "AnotherField" AS "AnotherAlias", MATCH (Title, MenuTitle) AGAINST (' . |
||
632 | '\'Two as One\') AS "Relevance" FROM "MyTable"', |
||
633 | $query->sql() |
||
634 | ); |
||
635 | } |
||
636 | |||
637 | /** |
||
638 | * Test passing in a LIMIT with OFFSET clause string. |
||
639 | */ |
||
640 | public function testLimitSetFromClauseString() { |
||
641 | $query = new SQLQuery(); |
||
642 | $query->setSelect('*'); |
||
643 | $query->setFrom('"SQLQueryTest_DO"'); |
||
644 | |||
645 | $query->setLimit('20 OFFSET 10'); |
||
646 | $limit = $query->getLimit(); |
||
647 | $this->assertEquals(20, $limit['limit']); |
||
648 | $this->assertEquals(10, $limit['start']); |
||
649 | } |
||
650 | |||
651 | View Code Duplication | public function testParameterisedInnerJoins() { |
|
673 | |||
674 | View Code Duplication | public function testParameterisedLeftJoins() { |
|
696 | |||
697 | /** |
||
698 | * Test deprecation of SQLQuery::getWhere working appropriately |
||
699 | */ |
||
700 | public function testDeprecatedGetWhere() { |
||
701 | // Temporarily disable deprecation |
||
702 | Deprecation::notification_version(null); |
||
703 | |||
704 | $query = new SQLQuery(); |
||
705 | $query->setSelect(array('"SQLQueryTest_DO"."Name"')); |
||
706 | $query->setFrom('"SQLQueryTest_DO"'); |
||
707 | $query->addWhere(array( |
||
708 | '"SQLQueryTest_DO"."Date" > ?' => '2012-08-08 12:00' |
||
709 | )); |
||
710 | $query->addWhere('"SQLQueryTest_DO"."Name" = \'Richard\''); |
||
711 | $query->addWhere(array( |
||
712 | '"SQLQueryTest_DO"."Meta" IN (?, \'Who?\', ?)' => array('Left', 'Right') |
||
713 | )); |
||
714 | |||
715 | $expectedSQL = <<<EOS |
||
716 | SELECT "SQLQueryTest_DO"."Name" |
||
717 | FROM "SQLQueryTest_DO" |
||
718 | WHERE ("SQLQueryTest_DO"."Date" > ?) |
||
719 | AND ("SQLQueryTest_DO"."Name" = 'Richard') |
||
720 | AND ("SQLQueryTest_DO"."Meta" IN (?, 'Who?', ?)) |
||
721 | EOS |
||
745 | |||
746 | /** |
||
747 | * Test deprecation of SQLQuery::setDelete/getDelete |
||
748 | */ |
||
749 | public function testDeprecatedSetDelete() { |
||
790 | } |
||
791 | |||
815 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.