Completed
Push — new-committers ( 29cb6f...bcba16 )
by Sam
12:18 queued 33s
created

SQLQueryTest   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 784
Duplicated Lines 29.21 %

Coupling/Cohesion

Components 2
Dependencies 9
Metric Value
wmc 53
lcom 2
cbo 9
dl 229
loc 784
rs 5.7142

37 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 4 1
A tearDown() 0 4 1
A testEmptyQueryReturnsNothing() 0 4 1
A testSelectWithLimitClause() 4 17 4
A testZeroLimitWithOffset() 4 15 4
A testNegativeLimit() 0 4 1
A testNegativeOffset() 0 4 1
A testNegativeOffsetAndLimit() 0 4 1
A testParameterisedInnerJoins() 22 22 1
A testParameterisedLeftJoins() 22 22 1
A testCount() 0 14 2
A testSelectFromBasicTable() 0 7 1
A testSelectFromUserSpecifiedFields() 0 6 1
A testSelectWithWhereClauseFilter() 0 11 1
A testSelectWithConstructorParameters() 0 6 1
A testSelectWithChainedMethods() 0 8 1
A testCanSortBy() 6 6 1
A testSelectWithChainedFilterParameters() 9 9 1
A testSelectWithOrderbyClause() 0 64 1
A testNullLimit() 10 10 1
A testZeroLimit() 10 10 1
B testReverseOrderBy() 0 32 1
B testFiltersOnID() 0 43 1
B testFiltersOnFK() 0 29 1
A testInnerJoin() 23 23 1
B testJoinSubSelect() 31 31 1
A testSetWhereAny() 0 12 1
B testSelectFirst() 44 44 4
B testSelectLast() 44 44 4
A testAggregate() 0 9 1
A testAggregateNoOrderByIfNoLimit() 0 21 1
A testOrderByContainingAggregateAndLimitOffset() 0 18 2
A testOrderByMultiple() 0 21 3
B testSelect() 0 28 1
A testLimitSetFromClauseString() 0 10 1
B testDeprecatedGetWhere() 0 45 1
B testDeprecatedSetDelete() 0 41 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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 Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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
2
3
/**
4
 * @package framework
5
 * @subpackage tests
6
 */
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() {
20
		parent::setUp();
21
		$this->oldDeprecation = Deprecation::dump_settings();
22
	}
23
24
	public function tearDown() {
25
		Deprecation::restore_settings($this->oldDeprecation);
26
		parent::tearDown();
27
	}
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() {
45
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
46
		$this->assertSQLEquals('', $query->sql($parameters));
47
	}
48
49
	public function testSelectFromBasicTable() {
50
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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");
0 ignored issues
show
Documentation introduced by
array('Foo', 'Bar') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
'FooBarTable' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
78
		$this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable", $query->sql($parameters));
79
		$query = new SQLQuery(array("Foo", "Bar"), "FooBarTable", array("Foo = 'Boo'"));
0 ignored issues
show
Documentation introduced by
array('Foo', 'Bar') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
'FooBarTable' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
80
		$this->assertSQLEquals("SELECT Foo, Bar FROM FooBarTable WHERE (Foo = 'Boo')", $query->sql($parameters));
81
	}
82
83
	public function testSelectWithChainedMethods() {
84
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
100
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
110 View Code Duplication
		if(!(DB::get_conn() instanceof MySQLDatabase || DB::get_conn() instanceof SQLite3Database
0 ignored issues
show
Bug introduced by
The class SQLite3Database does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
				|| DB::get_conn() instanceof PostgreSQLDatabase)) {
0 ignored issues
show
Bug introduced by
The class PostgreSQLDatabase does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
112
			$this->markTestIncomplete();
113
		}
114
115
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
116
		$query->setFrom("MyTable");
117
		$query->setLimit(99);
118
		$this->assertSQLEquals("SELECT * FROM MyTable LIMIT 99", $query->sql($parameters));
119
120
		// array limit with start (MySQL specific)
121
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
122
		$query->setFrom("MyTable");
123
		$query->setLimit(99, 97);
124
		$this->assertSQLEquals("SELECT * FROM MyTable LIMIT 99 OFFSET 97", $query->sql($parameters));
125
	}
126
127
	public function testSelectWithOrderbyClause() {
128
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
215 View Code Duplication
		if(!(DB::get_conn() instanceof MySQLDatabase || DB::get_conn() instanceof SQLite3Database
0 ignored issues
show
Bug introduced by
The class SQLite3Database does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
216
				|| DB::get_conn() instanceof PostgreSQLDatabase)) {
0 ignored issues
show
Bug introduced by
The class PostgreSQLDatabase does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
217
			$this->markTestIncomplete();
218
		}
219
220
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
221
		$query->setFrom("MyTable");
222
		$query->setLimit(0, 99);
223
224
		$this->assertSQLEquals(
225
			'SELECT * FROM MyTable LIMIT 0 OFFSET 99',
226
			$query->sql($parameters)
227
		);
228
	}
229
230
	/**
231
	 * @expectedException InvalidArgumentException
232
	 */
233
	public function testNegativeLimit() {
234
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
235
		$query->setLimit(-10);
236
	}
237
238
	/**
239
	 * @expectedException InvalidArgumentException
240
	 */
241
	public function testNegativeOffset() {
242
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
243
		$query->setLimit(1, -10);
244
	}
245
246
	/**
247
	 * @expectedException InvalidArgumentException
248
	 */
249
	public function testNegativeOffsetAndLimit() {
250
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
251
		$query->setLimit(-10, -10);
252
	}
253
254
	public function testReverseOrderBy() {
255
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
362
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
386
387
		// Test sub-select works
388
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
431
		// Test first from sequence
432
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
476
		// Test last in sequence
477
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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"');
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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"');
0 ignored issues
show
Documentation introduced by
'"MyTable"' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
652
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
653
		$query->setSelect(array('"SQLQueryTest_DO"."Name"', '"SubSelect"."Count"'));
654
		$query->setFrom('"SQLQueryTest_DO"');
655
		$query->addInnerJoin(
656
			'(SELECT "Title", COUNT(*) AS "Count" FROM "SQLQueryTestBase" GROUP BY "Title" HAVING "Title" NOT LIKE ?)',
657
			'"SQLQueryTest_DO"."Name" = "SubSelect"."Title"',
658
			'SubSelect',
659
			20,
660
			array('%MyName%')
661
		);
662
		$query->addWhere(array('"SQLQueryTest_DO"."Date" > ?' => '2012-08-08 12:00'));
663
664
		$this->assertSQLEquals('SELECT "SQLQueryTest_DO"."Name", "SubSelect"."Count"
665
			FROM "SQLQueryTest_DO" INNER JOIN (SELECT "Title", COUNT(*) AS "Count" FROM "SQLQueryTestBase"
666
		   GROUP BY "Title" HAVING "Title" NOT LIKE ?) AS "SubSelect" ON "SQLQueryTest_DO"."Name" =
667
		   "SubSelect"."Title"
668
			WHERE ("SQLQueryTest_DO"."Date" > ?)', $query->sql($parameters)
669
		);
670
		$this->assertEquals(array('%MyName%', '2012-08-08 12:00'), $parameters);
671
		$query->execute();
672
	}
673
674 View Code Duplication
	public function testParameterisedLeftJoins() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
675
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
676
		$query->setSelect(array('"SQLQueryTest_DO"."Name"', '"SubSelect"."Count"'));
677
		$query->setFrom('"SQLQueryTest_DO"');
678
		$query->addLeftJoin(
679
			'(SELECT "Title", COUNT(*) AS "Count" FROM "SQLQueryTestBase" GROUP BY "Title" HAVING "Title" NOT LIKE ?)',
680
			'"SQLQueryTest_DO"."Name" = "SubSelect"."Title"',
681
			'SubSelect',
682
			20,
683
			array('%MyName%')
684
		);
685
		$query->addWhere(array('"SQLQueryTest_DO"."Date" > ?' => '2012-08-08 12:00'));
686
687
		$this->assertSQLEquals('SELECT "SQLQueryTest_DO"."Name", "SubSelect"."Count"
688
			FROM "SQLQueryTest_DO" LEFT JOIN (SELECT "Title", COUNT(*) AS "Count" FROM "SQLQueryTestBase"
689
		   GROUP BY "Title" HAVING "Title" NOT LIKE ?) AS "SubSelect" ON "SQLQueryTest_DO"."Name" =
690
		   "SubSelect"."Title"
691
			WHERE ("SQLQueryTest_DO"."Date" > ?)', $query->sql($parameters)
692
		);
693
		$this->assertEquals(array('%MyName%', '2012-08-08 12:00'), $parameters);
694
		$query->execute();
695
	}
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();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
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
722
			;
723
		$expectedParameters = array('2012-08-08 12:00', 'Left', 'Right');
724
725
726
		// Check sql evaluation of this query maintains the parameters
727
		$sql = $query->sql($parameters);
728
		$this->assertSQLEquals($expectedSQL, $sql);
729
		$this->assertEquals($expectedParameters, $parameters);
730
731
		// Check that ->toAppropriateExpression()->setWhere doesn't modify the query
732
		$query->setWhere($query->toAppropriateExpression()->getWhere());
733
		$sql = $query->sql($parameters);
734
		$this->assertSQLEquals($expectedSQL, $sql);
735
		$this->assertEquals($expectedParameters, $parameters);
736
737
		// Check that getWhere are all flattened queries
738
		$expectedFlattened = array(
739
			'"SQLQueryTest_DO"."Date" > \'2012-08-08 12:00\'',
740
			'"SQLQueryTest_DO"."Name" = \'Richard\'',
741
			'"SQLQueryTest_DO"."Meta" IN (\'Left\', \'Who?\', \'Right\')'
742
		);
743
		$this->assertEquals($expectedFlattened, $query->getWhere());
744
	}
745
746
	/**
747
	 * Test deprecation of SQLQuery::setDelete/getDelete
748
	 */
749
	public function testDeprecatedSetDelete() {
750
		// Temporarily disable deprecation
751
		Deprecation::notification_version(null);
752
753
		$query = new SQLQuery();
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

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.

Loading history...
754
		$query->setSelect(array('"SQLQueryTest_DO"."Name"'));
755
		$query->setFrom('"SQLQueryTest_DO"');
756
		$query->setWhere(array('"SQLQueryTest_DO"."Name"' => 'Andrew'));
757
758
		// Check SQL for select
759
		$this->assertSQLEquals(<<<EOS
760
SELECT "SQLQueryTest_DO"."Name" FROM "SQLQueryTest_DO"
761
WHERE ("SQLQueryTest_DO"."Name" = ?)
762
EOS
763
			,
764
			$query->sql($parameters)
765
		);
766
		$this->assertEquals(array('Andrew'), $parameters);
767
768
		// Check setDelete works
769
		$query->setDelete(true);
0 ignored issues
show
Deprecated Code introduced by
The method SQLQuery::setDelete() has been deprecated with message: since version 4.0

This method 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 method will be removed from the class and what other method or class to use instead.

Loading history...
770
	$this->assertSQLEquals(<<<EOS
771
DELETE FROM "SQLQueryTest_DO"
772
WHERE ("SQLQueryTest_DO"."Name" = ?)
773
EOS
774
			,
775
			$query->sql($parameters)
776
		);
777
		$this->assertEquals(array('Andrew'), $parameters);
778
779
		// Check that setDelete back to false restores the state
780
		$query->setDelete(false);
0 ignored issues
show
Deprecated Code introduced by
The method SQLQuery::setDelete() has been deprecated with message: since version 4.0

This method 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 method will be removed from the class and what other method or class to use instead.

Loading history...
781
		$this->assertSQLEquals(<<<EOS
782
SELECT "SQLQueryTest_DO"."Name" FROM "SQLQueryTest_DO"
783
WHERE ("SQLQueryTest_DO"."Name" = ?)
784
EOS
785
			,
786
			$query->sql($parameters)
787
		);
788
		$this->assertEquals(array('Andrew'), $parameters);
789
	}
790
}
791
792
class SQLQueryTest_DO extends DataObject implements TestOnly {
793
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
794
		"Name" => "Varchar",
795
		"Meta" => "Varchar",
796
		"Common" => "Varchar",
797
		"Date" => "SS_Datetime"
798
	);
799
}
800
801
class SQLQueryTestBase extends DataObject implements TestOnly {
802
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
803
		"Title" => "Varchar",
804
	);
805
}
806
807
class SQLQueryTestChild extends SQLQueryTestBase {
808
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
809
		"Name" => "Varchar",
810
	);
811
812
	private static $has_one = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
813
	);
814
}
815