testGenerateAssociationQuerySelfJoinWithConditions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 55
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 39
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 55
rs 9.7692

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * DboMysqlTest file
4
 *
5
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://cakephp.org CakePHP(tm) Project
14
 * @package       Cake.Test.Case.Model.Datasource.Database
15
 * @since         CakePHP(tm) v 1.2.0
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
19
App::uses('Model', 'Model');
20
App::uses('AppModel', 'Model');
21
App::uses('Mysql', 'Model/Datasource/Database');
22
App::uses('CakeSchema', 'Model');
23
24
require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
25
26
/**
27
 * DboMysqlTest class
28
 *
29
 * @package       Cake.Test.Case.Model.Datasource.Database
30
 */
31
class MysqlTest extends CakeTestCase {
32
33
/**
34
 * autoFixtures property
35
 *
36
 * @var boolean
37
 */
38
	public $autoFixtures = false;
39
40
/**
41
 * fixtures property
42
 *
43
 * @var array
44
 */
45
	public $fixtures = array(
46
		'core.apple', 'core.article', 'core.articles_tag', 'core.attachment', 'core.comment',
47
		'core.sample', 'core.tag', 'core.user', 'core.post', 'core.author', 'core.data_test',
48
		'core.binary_test', 'core.inno'
49
	);
50
51
/**
52
 * The Dbo instance to be tested
53
 *
54
 * @var DboSource
55
 */
56
	public $Dbo = null;
57
58
/**
59
 * Sets up a Dbo class instance for testing
60
 *
61
 * @return void
62
 */
63
	public function setUp() {
64
		parent::setUp();
65
		$this->Dbo = ConnectionManager::getDataSource('test');
66
		if (!($this->Dbo instanceof Mysql)) {
67
			$this->markTestSkipped('The MySQL extension is not available.');
68
		}
69
		$this->_debug = Configure::read('debug');
70
		Configure::write('debug', 1);
71
		$this->model = ClassRegistry::init('MysqlTestModel');
72
	}
73
74
/**
75
 * Sets up a Dbo class instance for testing
76
 *
77
 * @return void
78
 */
79
	public function tearDown() {
80
		parent::tearDown();
81
		unset($this->model);
82
		ClassRegistry::flush();
83
		Configure::write('debug', $this->_debug);
84
	}
85
86
/**
87
 * Test Dbo value method
88
 *
89
 * @group quoting
90
 * @return void
91
 */
92
	public function testQuoting() {
93
		$result = $this->Dbo->fields($this->model);
94
		$expected = array(
95
			'`MysqlTestModel`.`id`',
96
			'`MysqlTestModel`.`client_id`',
97
			'`MysqlTestModel`.`name`',
98
			'`MysqlTestModel`.`login`',
99
			'`MysqlTestModel`.`passwd`',
100
			'`MysqlTestModel`.`addr_1`',
101
			'`MysqlTestModel`.`addr_2`',
102
			'`MysqlTestModel`.`zip_code`',
103
			'`MysqlTestModel`.`city`',
104
			'`MysqlTestModel`.`country`',
105
			'`MysqlTestModel`.`phone`',
106
			'`MysqlTestModel`.`fax`',
107
			'`MysqlTestModel`.`url`',
108
			'`MysqlTestModel`.`email`',
109
			'`MysqlTestModel`.`comments`',
110
			'`MysqlTestModel`.`last_login`',
111
			'`MysqlTestModel`.`created`',
112
			'`MysqlTestModel`.`updated`'
113
		);
114
		$this->assertEquals($expected, $result);
115
116
		$expected = 1.2;
117
		$result = $this->Dbo->value(1.2, 'float');
118
		$this->assertEquals($expected, $result);
119
120
		$expected = "'1,2'";
121
		$result = $this->Dbo->value('1,2', 'float');
122
		$this->assertEquals($expected, $result);
123
124
		$expected = "'4713e29446'";
125
		$result = $this->Dbo->value('4713e29446');
126
127
		$this->assertEquals($expected, $result);
128
129
		$expected = 'NULL';
130
		$result = $this->Dbo->value('', 'integer');
131
		$this->assertEquals($expected, $result);
132
133
		$expected = "'0'";
134
		$result = $this->Dbo->value('', 'boolean');
135
		$this->assertEquals($expected, $result);
136
137
		$expected = 10010001;
138
		$result = $this->Dbo->value(10010001);
139
		$this->assertEquals($expected, $result);
140
141
		$expected = "'00010010001'";
142
		$result = $this->Dbo->value('00010010001');
143
		$this->assertEquals($expected, $result);
144
	}
145
146
/**
147
 * test that localized floats don't cause trouble.
148
 *
149
 * @group quoting
150
 * @return void
151
 */
152
	public function testLocalizedFloats() {
153
		$this->skipIf(DS === '\\', 'The locale is not supported in Windows and affect the others tests.');
154
155
		$restore = setlocale(LC_NUMERIC, 0);
156
157
		$this->skipIf(setlocale(LC_NUMERIC, 'de_DE') === false, "The German locale isn't available.");
158
159
		$result = $this->Dbo->value(3.141593);
160
		$this->assertEquals('3.141593', $result);
161
162
		$result = $this->db->value(3.141593, 'float');
163
		$this->assertEquals('3.141593', $result);
164
165
		$result = $this->db->value(1234567.11, 'float');
166
		$this->assertEquals('1234567.11', $result);
167
168
		$result = $this->db->value(123456.45464748, 'float');
169
		$this->assertContains('123456.454647', $result);
170
171
		$result = $this->db->value(0.987654321, 'float');
172
		$this->assertEquals('0.987654321', (string)$result);
173
174
		$result = $this->db->value(2.2E-54, 'float');
175
		$this->assertEquals('2.2E-54', (string)$result);
176
177
		$result = $this->db->value(2.2E-54);
178
		$this->assertEquals('2.2E-54', (string)$result);
179
180
		setlocale(LC_NUMERIC, $restore);
181
	}
182
183
/**
184
 * test that scientific notations are working correctly
185
 *
186
 * @return void
187
 */
188
	public function testScientificNotation() {
189
		$result = $this->db->value(2.2E-54, 'float');
190
		$this->assertEquals('2.2E-54', (string)$result);
191
192
		$result = $this->db->value(2.2E-54);
193
		$this->assertEquals('2.2E-54', (string)$result);
194
	}
195
196
/**
197
 * testTinyintCasting method
198
 *
199
 *
200
 * @return void
201
 */
202
	public function testTinyintCasting() {
203
		$this->Dbo->cacheSources = false;
204
		$tableName = 'tinyint_' . uniqid();
205
		$this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
206
207
		$this->model = new CakeTestModel(array(
208
			'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
209
		));
210
211
		$result = $this->model->schema();
212
		$this->assertEquals('boolean', $result['bool']['type']);
213
		$this->assertEquals('integer', $result['small_int']['type']);
214
215
		$this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
216
		$result = $this->model->find('first');
217
		$this->assertTrue($result['Tinyint']['bool']);
218
		$this->assertSame($result['Tinyint']['small_int'], '5');
219
		$this->model->deleteAll(true);
220
221
		$this->assertTrue((bool)$this->model->save(array('bool' => 0, 'small_int' => 100)));
222
		$result = $this->model->find('first');
223
		$this->assertFalse($result['Tinyint']['bool']);
224
		$this->assertSame($result['Tinyint']['small_int'], '100');
225
		$this->model->deleteAll(true);
226
227
		$this->assertTrue((bool)$this->model->save(array('bool' => true, 'small_int' => 0)));
228
		$result = $this->model->find('first');
229
		$this->assertTrue($result['Tinyint']['bool']);
230
		$this->assertSame($result['Tinyint']['small_int'], '0');
231
		$this->model->deleteAll(true);
232
233
		$this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
234
	}
235
236
/**
237
 * testLastAffected method
238
 *
239
 *
240
 * @return void
241
 */
242
	public function testLastAffected() {
243
		$this->Dbo->cacheSources = false;
244
		$tableName = 'tinyint_' . uniqid();
245
		$this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
246
247
		$this->model = new CakeTestModel(array(
248
			'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
249
		));
250
251
		$this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
252
		$this->assertEquals(1, $this->model->find('count'));
253
		$this->model->deleteAll(true);
254
		$result = $this->Dbo->lastAffected();
255
		$this->assertEquals(1, $result);
256
		$this->assertEquals(0, $this->model->find('count'));
257
258
		$this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
259
	}
260
261
/**
262
 * testIndexDetection method
263
 *
264
 * @group indices
265
 * @return void
266
 */
267
	public function testIndexDetection() {
268
		$this->Dbo->cacheSources = false;
269
270
		$name = $this->Dbo->fullTableName('simple');
271
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
272
		$expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
273
		$result = $this->Dbo->index('simple', false);
274
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
275
		$this->assertEquals($expected, $result);
276
277
		$name = $this->Dbo->fullTableName('bigint');
278
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id bigint(20) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
279
		$expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
280
		$result = $this->Dbo->index('bigint', false);
281
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
282
		$this->assertEquals($expected, $result);
283
284
		$name = $this->Dbo->fullTableName('with_a_key');
285
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ));');
286
		$expected = array(
287
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
288
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
289
		);
290
		$result = $this->Dbo->index('with_a_key', false);
291
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
292
		$this->assertEquals($expected, $result);
293
294
		$name = $this->Dbo->fullTableName('with_two_keys');
295
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ));');
296
		$expected = array(
297
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
298
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
299
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
300
		);
301
		$result = $this->Dbo->index('with_two_keys', false);
302
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
303
		$this->assertEquals($expected, $result);
304
305
		$name = $this->Dbo->fullTableName('with_compound_keys');
306
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ));');
307
		$expected = array(
308
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
309
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
310
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
311
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
312
		);
313
		$result = $this->Dbo->index('with_compound_keys', false);
314
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
315
		$this->assertEquals($expected, $result);
316
317
		$name = $this->Dbo->fullTableName('with_multiple_compound_keys');
318
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ), KEY `other_way` ( `small_int`, `bool` ));');
319
		$expected = array(
320
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
321
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
322
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
323
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
324
			'other_way' => array('column' => array('small_int', 'bool'), 'unique' => 0),
325
		);
326
		$result = $this->Dbo->index('with_multiple_compound_keys', false);
327
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
328
		$this->assertEquals($expected, $result);
329
330
		$name = $this->Dbo->fullTableName('with_fulltext');
331
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, name varchar(255), description text, primary key(id), FULLTEXT KEY `MyFtIndex` ( `name`, `description` )) ENGINE=MyISAM;');
332
		$expected = array(
333
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
334
			'MyFtIndex' => array('column' => array('name', 'description'), 'type' => 'fulltext')
335
		);
336
		$result = $this->Dbo->index('with_fulltext', false);
337
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
338
		$this->assertEquals($expected, $result);
339
340
		$name = $this->Dbo->fullTableName('with_text_index');
341
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, text_field text, primary key(id), KEY `text_index` ( `text_field`(20) ));');
342
		$expected = array(
343
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
344
			'text_index' => array('column' => 'text_field', 'unique' => 0, 'length' => array('text_field' => 20)),
345
		);
346
		$result = $this->Dbo->index('with_text_index', false);
347
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
348
		$this->assertEquals($expected, $result);
349
350
		$name = $this->Dbo->fullTableName('with_compound_text_index');
351
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, text_field1 text, text_field2 text, primary key(id), KEY `text_index` ( `text_field1`(20), `text_field2`(20) ));');
352
		$expected = array(
353
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
354
			'text_index' => array('column' => array('text_field1', 'text_field2'), 'unique' => 0, 'length' => array('text_field1' => 20, 'text_field2' => 20)),
355
		);
356
		$result = $this->Dbo->index('with_compound_text_index', false);
357
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
358
		$this->assertEquals($expected, $result);
359
	}
360
361
/**
362
 * testBuildColumn method
363
 *
364
 * @return void
365
 */
366
	public function testBuildColumn() {
367
		$restore = $this->Dbo->columns;
368
		$this->Dbo->columns = array('varchar(255)' => 1);
369
		$data = array(
370
			'name' => 'testName',
371
			'type' => 'varchar(255)',
372
			'default',
373
			'null' => true,
374
			'key',
375
			'comment' => 'test'
376
		);
377
		$result = $this->Dbo->buildColumn($data);
378
		$expected = '`testName`  DEFAULT NULL COMMENT \'test\'';
379
		$this->assertEquals($expected, $result);
380
381
		$data = array(
382
			'name' => 'testName',
383
			'type' => 'varchar(255)',
384
			'default',
385
			'null' => true,
386
			'key',
387
			'charset' => 'utf8',
388
			'collate' => 'utf8_unicode_ci'
389
		);
390
		$result = $this->Dbo->buildColumn($data);
391
		$expected = '`testName`  CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL';
392
		$this->assertEquals($expected, $result);
393
		$this->Dbo->columns = $restore;
394
	}
395
396
/**
397
 * MySQL 4.x returns index data in a different format,
398
 * Using a mock ensure that MySQL 4.x output is properly parsed.
399
 *
400
 * @group indices
401
 * @return void
402
 */
403
	public function testIndexOnMySQL4Output() {
404
		$name = $this->Dbo->fullTableName('simple');
405
406
		$mockDbo = $this->getMock('Mysql', array('connect', '_execute', 'getVersion'));
407
		$columnData = array(
408
			array('0' => array(
409
				'Table' => 'with_compound_keys',
410
				'Non_unique' => '0',
411
				'Key_name' => 'PRIMARY',
412
				'Seq_in_index' => '1',
413
				'Column_name' => 'id',
414
				'Collation' => 'A',
415
				'Cardinality' => '0',
416
				'Sub_part' => null,
417
				'Packed' => null,
418
				'Null' => '',
419
				'Index_type' => 'BTREE',
420
				'Comment' => ''
421
			)),
422
			array('0' => array(
423
				'Table' => 'with_compound_keys',
424
				'Non_unique' => '1',
425
				'Key_name' => 'pointless_bool',
426
				'Seq_in_index' => '1',
427
				'Column_name' => 'bool',
428
				'Collation' => 'A',
429
				'Cardinality' => null,
430
				'Sub_part' => null,
431
				'Packed' => null,
432
				'Null' => 'YES',
433
				'Index_type' => 'BTREE',
434
				'Comment' => ''
435
			)),
436
			array('0' => array(
437
				'Table' => 'with_compound_keys',
438
				'Non_unique' => '1',
439
				'Key_name' => 'pointless_small_int',
440
				'Seq_in_index' => '1',
441
				'Column_name' => 'small_int',
442
				'Collation' => 'A',
443
				'Cardinality' => null,
444
				'Sub_part' => null,
445
				'Packed' => null,
446
				'Null' => 'YES',
447
				'Index_type' => 'BTREE',
448
				'Comment' => ''
449
			)),
450
			array('0' => array(
451
				'Table' => 'with_compound_keys',
452
				'Non_unique' => '1',
453
				'Key_name' => 'one_way',
454
				'Seq_in_index' => '1',
455
				'Column_name' => 'bool',
456
				'Collation' => 'A',
457
				'Cardinality' => null,
458
				'Sub_part' => null,
459
				'Packed' => null,
460
				'Null' => 'YES',
461
				'Index_type' => 'BTREE',
462
				'Comment' => ''
463
			)),
464
			array('0' => array(
465
				'Table' => 'with_compound_keys',
466
				'Non_unique' => '1',
467
				'Key_name' => 'one_way',
468
				'Seq_in_index' => '2',
469
				'Column_name' => 'small_int',
470
				'Collation' => 'A',
471
				'Cardinality' => null,
472
				'Sub_part' => null,
473
				'Packed' => null,
474
				'Null' => 'YES',
475
				'Index_type' => 'BTREE',
476
				'Comment' => ''
477
			))
478
		);
479
480
		$mockDbo->expects($this->once())->method('getVersion')->will($this->returnValue('4.1'));
481
		$resultMock = $this->getMock('PDOStatement', array('fetch'));
482
		$mockDbo->expects($this->once())
483
			->method('_execute')
484
			->with('SHOW INDEX FROM ' . $name)
485
			->will($this->returnValue($resultMock));
486
487
		foreach ($columnData as $i => $data) {
488
			$resultMock->expects($this->at($i))->method('fetch')->will($this->returnValue((object)$data));
489
		}
490
491
		$result = $mockDbo->index($name, false);
492
		$expected = array(
493
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
494
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
495
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
496
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
497
		);
498
		$this->assertEquals($expected, $result);
499
	}
500
501
/**
502
 * testColumn method
503
 *
504
 * @return void
505
 */
506
	public function testColumn() {
507
		$result = $this->Dbo->column('varchar(50)');
508
		$expected = 'string';
509
		$this->assertEquals($expected, $result);
510
511
		$result = $this->Dbo->column('text');
512
		$expected = 'text';
513
		$this->assertEquals($expected, $result);
514
515
		$result = $this->Dbo->column('int(11)');
516
		$expected = 'integer';
517
		$this->assertEquals($expected, $result);
518
519
		$result = $this->Dbo->column('int(11) unsigned');
520
		$expected = 'integer';
521
		$this->assertEquals($expected, $result);
522
523
		$result = $this->Dbo->column('bigint(20)');
524
		$expected = 'biginteger';
525
		$this->assertEquals($expected, $result);
526
527
		$result = $this->Dbo->column('tinyint(1)');
528
		$expected = 'boolean';
529
		$this->assertEquals($expected, $result);
530
531
		$result = $this->Dbo->column('boolean');
532
		$expected = 'boolean';
533
		$this->assertEquals($expected, $result);
534
535
		$result = $this->Dbo->column('float');
536
		$expected = 'float';
537
		$this->assertEquals($expected, $result);
538
539
		$result = $this->Dbo->column('float unsigned');
540
		$expected = 'float';
541
		$this->assertEquals($expected, $result);
542
543
		$result = $this->Dbo->column('double unsigned');
544
		$expected = 'float';
545
		$this->assertEquals($expected, $result);
546
547
		$result = $this->Dbo->column('decimal(14,7) unsigned');
548
		$expected = 'float';
549
		$this->assertEquals($expected, $result);
550
	}
551
552
/**
553
 * testAlterSchemaIndexes method
554
 *
555
 * @group indices
556
 * @return void
557
 */
558
	public function testAlterSchemaIndexes() {
559
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
0 ignored issues
show
Bug introduced by
The property testing does not seem to exist in DboSource.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
560
		$table = $this->Dbo->fullTableName('altertest');
561
562
		$schemaA = new CakeSchema(array(
563
			'name' => 'AlterTest1',
564
			'connection' => 'test',
565
			'altertest' => array(
566
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
567
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
568
				'group1' => array('type' => 'integer', 'null' => true),
569
				'group2' => array('type' => 'integer', 'null' => true)
570
		)));
571
		$result = $this->Dbo->createSchema($schemaA);
572
		$this->assertContains('`id` int(11) DEFAULT 0 NOT NULL,', $result);
573
		$this->assertContains('`name` varchar(50) NOT NULL,', $result);
574
		$this->assertContains('`group1` int(11) DEFAULT NULL', $result);
575
		$this->assertContains('`group2` int(11) DEFAULT NULL', $result);
576
577
		//Test that the string is syntactically correct
578
		$query = $this->Dbo->getConnection()->prepare($result);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $this->Dbo->getConnection() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
579
		$this->assertEquals($query->queryString, $result);
580
581
		$schemaB = new CakeSchema(array(
582
			'name' => 'AlterTest2',
583
			'connection' => 'test',
584
			'altertest' => array(
585
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
586
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
587
				'group1' => array('type' => 'integer', 'null' => true),
588
				'group2' => array('type' => 'integer', 'null' => true),
589
				'indexes' => array(
590
					'name_idx' => array('column' => 'name', 'unique' => 0),
591
					'group_idx' => array('column' => 'group1', 'unique' => 0),
592
					'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
593
					'PRIMARY' => array('column' => 'id', 'unique' => 1))
594
		)));
595
596
		$result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
597
		$this->assertContains("ALTER TABLE $table", $result);
598
		$this->assertContains('ADD KEY `name_idx` (`name`),', $result);
599
		$this->assertContains('ADD KEY `group_idx` (`group1`),', $result);
600
		$this->assertContains('ADD KEY `compound_idx` (`group1`, `group2`),', $result);
601
		$this->assertContains('ADD PRIMARY KEY  (`id`);', $result);
602
603
		//Test that the string is syntactically correct
604
		$query = $this->Dbo->getConnection()->prepare($result);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $this->Dbo->getConnection() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
605
		$this->assertEquals($query->queryString, $result);
606
607
		// Change three indexes, delete one and add another one
608
		$schemaC = new CakeSchema(array(
609
			'name' => 'AlterTest3',
610
			'connection' => 'test',
611
			'altertest' => array(
612
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
613
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
614
				'group1' => array('type' => 'integer', 'null' => true),
615
				'group2' => array('type' => 'integer', 'null' => true),
616
				'indexes' => array(
617
					'name_idx' => array('column' => 'name', 'unique' => 1),
618
					'group_idx' => array('column' => 'group2', 'unique' => 0),
619
					'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
620
					'id_name_idx' => array('column' => array('id', 'name'), 'unique' => 0))
621
		)));
622
623
		$result = $this->Dbo->alterSchema($schemaC->compare($schemaB));
624
		$this->assertContains("ALTER TABLE $table", $result);
625
		$this->assertContains('DROP PRIMARY KEY,', $result);
626
		$this->assertContains('DROP KEY `name_idx`,', $result);
627
		$this->assertContains('DROP KEY `group_idx`,', $result);
628
		$this->assertContains('DROP KEY `compound_idx`,', $result);
629
		$this->assertContains('ADD KEY `id_name_idx` (`id`, `name`),', $result);
630
		$this->assertContains('ADD UNIQUE KEY `name_idx` (`name`),', $result);
631
		$this->assertContains('ADD KEY `group_idx` (`group2`),', $result);
632
		$this->assertContains('ADD KEY `compound_idx` (`group2`, `group1`);', $result);
633
634
		$query = $this->Dbo->getConnection()->prepare($result);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $this->Dbo->getConnection() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
635
		$this->assertEquals($query->queryString, $result);
636
637
		// Compare us to ourself.
638
		$this->assertEquals(array(), $schemaC->compare($schemaC));
639
640
		// Drop the indexes
641
		$result = $this->Dbo->alterSchema($schemaA->compare($schemaC));
642
643
		$this->assertContains("ALTER TABLE $table", $result);
644
		$this->assertContains('DROP KEY `name_idx`,', $result);
645
		$this->assertContains('DROP KEY `group_idx`,', $result);
646
		$this->assertContains('DROP KEY `compound_idx`,', $result);
647
		$this->assertContains('DROP KEY `id_name_idx`;', $result);
648
649
		$query = $this->Dbo->getConnection()->prepare($result);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $this->Dbo->getConnection() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
650
		$this->assertEquals($query->queryString, $result);
651
	}
652
653
/**
654
 * test saving and retrieval of blobs
655
 *
656
 * @return void
657
 */
658
	public function testBlobSaving() {
659
		$this->loadFixtures('BinaryTest');
660
		$this->Dbo->cacheSources = false;
661
		$data = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
662
663
		$model = new CakeTestModel(array('name' => 'BinaryTest', 'ds' => 'test'));
664
		$model->save(compact('data'));
665
666
		$result = $model->find('first');
667
		$this->assertEquals($data, $result['BinaryTest']['data']);
668
	}
669
670
/**
671
 * test altering the table settings with schema.
672
 *
673
 * @return void
674
 */
675
	public function testAlteringTableParameters() {
676
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
0 ignored issues
show
Bug introduced by
The property testing does not seem to exist in DboSource.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
677
678
		$schemaA = new CakeSchema(array(
679
			'name' => 'AlterTest1',
680
			'connection' => 'test',
681
			'altertest' => array(
682
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
683
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
684
				'tableParameters' => array(
685
					'charset' => 'latin1',
686
					'collate' => 'latin1_general_ci',
687
					'engine' => 'MyISAM'
688
				)
689
			)
690
		));
691
		$this->Dbo->rawQuery($this->Dbo->createSchema($schemaA));
692
		$schemaB = new CakeSchema(array(
693
			'name' => 'AlterTest1',
694
			'connection' => 'test',
695
			'altertest' => array(
696
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
697
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
698
				'tableParameters' => array(
699
					'charset' => 'utf8',
700
					'collate' => 'utf8_general_ci',
701
					'engine' => 'InnoDB'
702
				)
703
			)
704
		));
705
		$result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
706
		$this->assertContains('DEFAULT CHARSET=utf8', $result);
707
		$this->assertContains('ENGINE=InnoDB', $result);
708
		$this->assertContains('COLLATE=utf8_general_ci', $result);
709
710
		$this->Dbo->rawQuery($result);
711
		$result = $this->Dbo->listDetailedSources($this->Dbo->fullTableName('altertest', false, false));
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DboSource as the method listDetailedSources() does only exist in the following sub-classes of DboSource: Mysql. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
712
		$this->assertEquals('utf8_general_ci', $result['Collation']);
713
		$this->assertEquals('InnoDB', $result['Engine']);
714
		$this->assertEquals('utf8', $result['charset']);
715
716
		$this->Dbo->rawQuery($this->Dbo->dropSchema($schemaA));
717
	}
718
719
/**
720
 * test alterSchema on two tables.
721
 *
722
 * @return void
723
 */
724 View Code Duplication
	public function testAlteringTwoTables() {
725
		$schema1 = new CakeSchema(array(
726
			'name' => 'AlterTest1',
727
			'connection' => 'test',
728
			'altertest' => array(
729
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
730
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
731
			),
732
			'other_table' => array(
733
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
734
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
735
			)
736
		));
737
		$schema2 = new CakeSchema(array(
738
			'name' => 'AlterTest1',
739
			'connection' => 'test',
740
			'altertest' => array(
741
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
742
				'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
743
			),
744
			'other_table' => array(
745
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
746
				'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
747
			)
748
		));
749
		$result = $this->Dbo->alterSchema($schema2->compare($schema1));
750
		$this->assertEquals(2, substr_count($result, 'field_two'), 'Too many fields');
751
	}
752
753
/**
754
 * testReadTableParameters method
755
 *
756
 * @return void
757
 */
758
	public function testReadTableParameters() {
759
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
0 ignored issues
show
Bug introduced by
The property testing does not seem to exist in DboSource.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
760
		$tableName = 'tinyint_' . uniqid();
761
		$table = $this->Dbo->fullTableName($tableName);
762
		$this->Dbo->rawQuery('CREATE TABLE ' . $table . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;');
763
		$result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
764
		$this->Dbo->rawQuery('DROP TABLE ' . $table);
765
		$expected = array(
766
			'charset' => 'utf8',
767
			'collate' => 'utf8_unicode_ci',
768
			'engine' => 'InnoDB');
769
		$this->assertEquals($expected, $result);
770
771
		$table = $this->Dbo->fullTableName($tableName);
772
		$this->Dbo->rawQuery('CREATE TABLE ' . $table . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_general_ci;');
773
		$result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
774
		$this->Dbo->rawQuery('DROP TABLE ' . $table);
775
		$expected = array(
776
			'charset' => 'cp1250',
777
			'collate' => 'cp1250_general_ci',
778
			'engine' => 'MyISAM');
779
		$this->assertEquals($expected, $result);
780
	}
781
782
/**
783
 * testBuildTableParameters method
784
 *
785
 * @return void
786
 */
787
	public function testBuildTableParameters() {
788
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
0 ignored issues
show
Bug introduced by
The property testing does not seem to exist in DboSource.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
789
		$data = array(
790
			'charset' => 'utf8',
791
			'collate' => 'utf8_unicode_ci',
792
			'engine' => 'InnoDB');
793
		$result = $this->Dbo->buildTableParameters($data);
794
		$expected = array(
795
			'DEFAULT CHARSET=utf8',
796
			'COLLATE=utf8_unicode_ci',
797
			'ENGINE=InnoDB');
798
		$this->assertEquals($expected, $result);
799
	}
800
801
/**
802
 * testGetCharsetName method
803
 *
804
 * @return void
805
 */
806
	public function testGetCharsetName() {
807
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
0 ignored issues
show
Bug introduced by
The property testing does not seem to exist in DboSource.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
808
		$result = $this->Dbo->getCharsetName('utf8_unicode_ci');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DboSource as the method getCharsetName() does only exist in the following sub-classes of DboSource: Mysql. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
809
		$this->assertEquals('utf8', $result);
810
		$result = $this->Dbo->getCharsetName('cp1250_general_ci');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DboSource as the method getCharsetName() does only exist in the following sub-classes of DboSource: Mysql. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
811
		$this->assertEquals('cp1250', $result);
812
	}
813
814
/**
815
 * testGetCharsetNameCaching method
816
 *
817
 * @return void
818
 */
819
	public function testGetCharsetNameCaching() {
820
		$db = $this->getMock('Mysql', array('connect', '_execute', 'getVersion'));
821
		$queryResult = $this->getMock('PDOStatement');
822
823
		$db->expects($this->exactly(2))->method('getVersion')->will($this->returnValue('5.1'));
824
825
		$db->expects($this->exactly(1))
826
			->method('_execute')
827
			->with('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?', array('utf8_unicode_ci'))
828
			->will($this->returnValue($queryResult));
829
830
		$queryResult->expects($this->once())
831
			->method('fetch')
832
			->with(PDO::FETCH_ASSOC)
833
			->will($this->returnValue(array('CHARACTER_SET_NAME' => 'utf8')));
834
835
		$result = $db->getCharsetName('utf8_unicode_ci');
836
		$this->assertEquals('utf8', $result);
837
838
		$result = $db->getCharsetName('utf8_unicode_ci');
839
		$this->assertEquals('utf8', $result);
840
	}
841
842
/**
843
 * test that changing the virtualFieldSeparator allows for __ fields.
844
 *
845
 * @return void
846
 */
847
	public function testVirtualFieldSeparators() {
848
		$this->loadFixtures('BinaryTest');
849
		$model = new CakeTestModel(array('table' => 'binary_tests', 'ds' => 'test', 'name' => 'BinaryTest'));
850
		$model->virtualFields = array(
851
			'other__field' => 'SUM(id)'
852
		);
853
854
		$this->Dbo->virtualFieldSeparator = '_$_';
855
		$result = $this->Dbo->fields($model, null, array('data', 'other__field'));
856
857
		$expected = array('`BinaryTest`.`data`', '(SUM(id)) AS  `BinaryTest_$_other__field`');
858
		$this->assertEquals($expected, $result);
859
	}
860
861
/**
862
 * Test describe() on a fixture.
863
 *
864
 * @return void
865
 */
866
	public function testDescribe() {
867
		$this->loadFixtures('Apple');
868
869
		$model = new Apple();
870
		$result = $this->Dbo->describe($model);
871
872
		$this->assertTrue(isset($result['id']));
873
		$this->assertTrue(isset($result['color']));
874
875
		$result = $this->Dbo->describe($model->useTable);
876
877
		$this->assertTrue(isset($result['id']));
878
		$this->assertTrue(isset($result['color']));
879
	}
880
881
/**
882
 * test that a describe() gets additional fieldParameters
883
 *
884
 * @return void
885
 */
886
	public function testDescribeGettingFieldParameters() {
887
		$schema = new CakeSchema(array(
888
			'connection' => 'test',
889
			'testdescribes' => array(
890
				'id' => array('type' => 'integer', 'key' => 'primary'),
891
				'stringy' => array(
892
					'type' => 'string',
893
					'null' => true,
894
					'charset' => 'cp1250',
895
					'collate' => 'cp1250_general_ci',
896
				),
897
				'other_col' => array(
898
					'type' => 'string',
899
					'null' => false,
900
					'charset' => 'latin1',
901
					'comment' => 'Test Comment'
902
				)
903
			)
904
		));
905
906
		$this->Dbo->execute($this->Dbo->createSchema($schema));
907
		$model = new CakeTestModel(array('table' => 'testdescribes', 'name' => 'Testdescribes'));
908
		$result = $model->getDataSource()->describe($model);
909
		$this->Dbo->execute($this->Dbo->dropSchema($schema));
910
911
		$this->assertEquals('cp1250_general_ci', $result['stringy']['collate']);
912
		$this->assertEquals('cp1250', $result['stringy']['charset']);
913
		$this->assertEquals('Test Comment', $result['other_col']['comment']);
914
	}
915
916
/**
917
 * Test that two columns with key => primary doesn't create invalid sql.
918
 *
919
 * @return void
920
 */
921
	public function testTwoColumnsWithPrimaryKey() {
922
		$schema = new CakeSchema(array(
923
			'connection' => 'test',
924
			'roles_users' => array(
925
				'role_id' => array(
926
					'type' => 'integer',
927
					'null' => false,
928
					'default' => null,
929
					'key' => 'primary'
930
				),
931
				'user_id' => array(
932
					'type' => 'integer',
933
					'null' => false,
934
					'default' => null,
935
					'key' => 'primary'
936
				),
937
				'indexes' => array(
938
					'user_role_index' => array(
939
						'column' => array('role_id', 'user_id'),
940
						'unique' => 1
941
					),
942
					'user_index' => array(
943
						'column' => 'user_id',
944
						'unique' => 0
945
					)
946
				),
947
			)
948
		));
949
950
		$result = $this->Dbo->createSchema($schema);
951
		$this->assertContains('`role_id` int(11) NOT NULL,', $result);
952
		$this->assertContains('`user_id` int(11) NOT NULL,', $result);
953
	}
954
955
/**
956
 * Test that the primary flag is handled correctly.
957
 *
958
 * @return void
959
 */
960
	public function testCreateSchemaAutoPrimaryKey() {
961
		$schema = new CakeSchema();
962
		$schema->tables = array(
963
			'no_indexes' => array(
964
				'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
965
				'data' => array('type' => 'integer', 'null' => false),
966
				'indexes' => array(),
967
			)
968
		);
969
		$result = $this->Dbo->createSchema($schema, 'no_indexes');
970
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
971
		$this->assertNotContains('UNIQUE KEY', $result);
972
973
		$schema->tables = array(
974
			'primary_index' => array(
975
				'id' => array('type' => 'integer', 'null' => false),
976
				'data' => array('type' => 'integer', 'null' => false),
977
				'indexes' => array(
978
					'PRIMARY' => array('column' => 'id', 'unique' => 1),
979
					'some_index' => array('column' => 'data', 'unique' => 1)
980
				),
981
			)
982
		);
983
		$result = $this->Dbo->createSchema($schema, 'primary_index');
984
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
985
		$this->assertContains('UNIQUE KEY `some_index` (`data`)', $result);
986
987
		$schema->tables = array(
988
			'primary_flag_has_index' => array(
989
				'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
990
				'data' => array('type' => 'integer', 'null' => false),
991
				'indexes' => array(
992
					'some_index' => array('column' => 'data', 'unique' => 1)
993
				),
994
			)
995
		);
996
		$result = $this->Dbo->createSchema($schema, 'primary_flag_has_index');
997
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
998
		$this->assertContains('UNIQUE KEY `some_index` (`data`)', $result);
999
	}
1000
1001
/**
1002
 * Tests that listSources method sends the correct query and parses the result accordingly
1003
 * @return void
1004
 */
1005
	public function testListSources() {
1006
		$db = $this->getMock('Mysql', array('connect', '_execute'));
1007
		$queryResult = $this->getMock('PDOStatement');
1008
		$db->expects($this->once())
1009
			->method('_execute')
1010
			->with('SHOW TABLES FROM `cake`')
1011
			->will($this->returnValue($queryResult));
1012
		$queryResult->expects($this->at(0))
1013
			->method('fetch')
1014
			->will($this->returnValue(array('cake_table')));
1015
		$queryResult->expects($this->at(1))
1016
			->method('fetch')
1017
			->will($this->returnValue(array('another_table')));
1018
		$queryResult->expects($this->at(2))
1019
			->method('fetch')
1020
			->will($this->returnValue(null));
1021
1022
		$tables = $db->listSources();
1023
		$this->assertEquals(array('cake_table', 'another_table'), $tables);
1024
	}
1025
1026
/**
1027
 * test that listDetailedSources with a named table that doesn't exist.
1028
 *
1029
 * @return void
1030
 */
1031
	public function testListDetailedSourcesNamed() {
1032
		$this->loadFixtures('Apple');
1033
1034
		$result = $this->Dbo->listDetailedSources('imaginary');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DboSource as the method listDetailedSources() does only exist in the following sub-classes of DboSource: Mysql. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1035
		$this->assertEquals(array(), $result, 'Should be empty when table does not exist.');
1036
1037
		$result = $this->Dbo->listDetailedSources();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DboSource as the method listDetailedSources() does only exist in the following sub-classes of DboSource: Mysql. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1038
		$tableName = $this->Dbo->fullTableName('apples', false, false);
1039
		$this->assertTrue(isset($result[$tableName]), 'Key should exist');
1040
	}
1041
1042
/**
1043
 * Tests that getVersion method sends the correct query for getting the mysql version
1044
 * @return void
1045
 */
1046
	public function testGetVersion() {
1047
		$version = $this->Dbo->getVersion();
1048
		$this->assertTrue(is_string($version));
1049
	}
1050
1051
/**
1052
 * Tests that getVersion method sends the correct query for getting the client encoding
1053
 * @return void
1054
 */
1055
	public function testGetEncoding() {
1056
		$db = $this->getMock('Mysql', array('connect', '_execute'));
1057
		$queryResult = $this->getMock('PDOStatement');
1058
1059
		$db->expects($this->once())
1060
			->method('_execute')
1061
			->with('SHOW VARIABLES LIKE ?', array('character_set_client'))
1062
			->will($this->returnValue($queryResult));
1063
		$result = new StdClass;
1064
		$result->Value = 'utf-8';
1065
		$queryResult->expects($this->once())
1066
			->method('fetchObject')
1067
			->will($this->returnValue($result));
1068
1069
		$encoding = $db->getEncoding();
1070
		$this->assertEquals('utf-8', $encoding);
1071
	}
1072
1073
/**
1074
 * testFieldDoubleEscaping method
1075
 *
1076
 * @return void
1077
 */
1078
	public function testFieldDoubleEscaping() {
1079
		$db = $this->Dbo->config['database'];
1080
		$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1081
		$test->config['database'] = $db;
1082
1083
		$this->Model = $this->getMock('Article2', array('getDataSource'));
1084
		$this->Model->alias = 'Article';
1085
		$this->Model->expects($this->any())
1086
			->method('getDataSource')
1087
			->will($this->returnValue($test));
1088
1089
		$this->assertEquals('`Article`.`id`', $this->Model->escapeField());
1090
		$result = $test->fields($this->Model, null, $this->Model->escapeField());
1091
		$this->assertEquals(array('`Article`.`id`'), $result);
1092
1093
		$test->expects($this->at(0))->method('execute')
1094
			->with('SELECT `Article`.`id` FROM ' . $test->fullTableName('articles') . ' AS `Article`   WHERE 1 = 1');
1095
1096
		$result = $test->read($this->Model, array(
1097
			'fields' => $this->Model->escapeField(),
1098
			'conditions' => null,
1099
			'recursive' => -1
1100
		));
1101
1102
		$test->startQuote = '[';
1103
		$test->endQuote = ']';
1104
		$this->assertEquals('[Article].[id]', $this->Model->escapeField());
1105
1106
		$result = $test->fields($this->Model, null, $this->Model->escapeField());
1107
		$this->assertEquals(array('[Article].[id]'), $result);
1108
1109
		$test->expects($this->at(0))->method('execute')
1110
			->with('SELECT [Article].[id] FROM ' . $test->fullTableName('articles') . ' AS [Article]   WHERE 1 = 1');
1111
		$result = $test->read($this->Model, array(
1112
			'fields' => $this->Model->escapeField(),
1113
			'conditions' => null,
1114
			'recursive' => -1
1115
		));
1116
	}
1117
1118
/**
1119
 * testGenerateAssociationQuerySelfJoin method
1120
 *
1121
 * @return void
1122
 */
1123
	public function testGenerateAssociationQuerySelfJoin() {
1124
		$this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1125
		$this->startTime = microtime(true);
1126
		$this->Model = new Article2();
1127
		$this->_buildRelatedModels($this->Model);
1128
		$this->_buildRelatedModels($this->Model->Category2);
1129
		$this->Model->Category2->ChildCat = new Category2();
1130
		$this->Model->Category2->ParentCat = new Category2();
1131
1132
		$queryData = array();
1133
1134
		foreach ($this->Model->Category2->associations() as $type) {
1135
			foreach ($this->Model->Category2->{$type} as $assoc => $assocData) {
1136
				$linkModel = $this->Model->Category2->{$assoc};
1137
				$external = isset($assocData['external']);
1138
1139
				if ($this->Model->Category2->alias === $linkModel->alias && $type !== 'hasAndBelongsToMany' && $type !== 'hasMany') {
1140
					$result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
0 ignored issues
show
Bug introduced by
The variable $null seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1141
					$this->assertFalse(empty($result));
1142
				} else {
1143
					if ($this->Model->Category2->useDbConfig === $linkModel->useDbConfig) {
1144
						$result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
0 ignored issues
show
Bug introduced by
The variable $null seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1145
						$this->assertFalse(empty($result));
1146
					}
1147
				}
1148
			}
1149
		}
1150
1151
		$query = $this->Dbo->generateAssociationQuery($this->Model->Category2, $null, null, null, null, $queryData, false, $null);
0 ignored issues
show
Bug introduced by
The variable $null seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1152
		$this->assertRegExp('/^SELECT\s+(.+)FROM(.+)`Category2`\.`group_id`\s+=\s+`Group`\.`id`\)\s+LEFT JOIN(.+)WHERE\s+1 = 1\s*$/', $query);
1153
1154
		$this->Model = new TestModel4();
1155
		$this->Model->schema();
1156
		$this->_buildRelatedModels($this->Model);
1157
1158
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
1159
		$queryData = array();
1160
		$resultSet = null;
1161
		$null = null;
1162
1163
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1164
1165
		$_queryData = $queryData;
1166
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1167
		$this->assertTrue($result);
1168
1169
		$expected = array(
1170
			'conditions' => array(),
1171
			'fields' => array(
1172
				'`TestModel4`.`id`',
1173
				'`TestModel4`.`name`',
1174
				'`TestModel4`.`created`',
1175
				'`TestModel4`.`updated`',
1176
				'`TestModel4Parent`.`id`',
1177
				'`TestModel4Parent`.`name`',
1178
				'`TestModel4Parent`.`created`',
1179
				'`TestModel4Parent`.`updated`'
1180
			),
1181
			'joins' => array(
1182
				array(
1183
					'table' => $this->Dbo->fullTableName($this->Model),
1184
					'alias' => 'TestModel4Parent',
1185
					'type' => 'LEFT',
1186
					'conditions' => '`TestModel4`.`parent_id` = `TestModel4Parent`.`id`'
1187
				)
1188
			),
1189
			'order' => array(),
1190
			'limit' => array(),
1191
			'offset' => array(),
1192
			'group' => array(),
1193
			'callbacks' => null
1194
		);
1195
		$queryData['joins'][0]['table'] = $this->Dbo->fullTableName($queryData['joins'][0]['table']);
1196
		$this->assertEquals($expected, $queryData);
1197
1198
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1199
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
1200
		$this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
1201
		$this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
1202
		$this->assertRegExp('/\s+WHERE\s+1 = 1$/', $result);
1203
1204
		$params['assocData']['type'] = 'INNER';
1205
		$this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER';
1206
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $_queryData, $params['external'], $resultSet);
1207
		$this->assertTrue($result);
1208
		$this->assertEquals('INNER', $_queryData['joins'][0]['type']);
1209
	}
1210
1211
/**
1212
 * buildRelatedModels method
1213
 *
1214
 * @param Model $model
1215
 * @return void
1216
 */
1217
	protected function _buildRelatedModels(Model $model) {
1218
		foreach ($model->associations() as $type) {
1219
			foreach ($model->{$type} as $assocData) {
1220
				if (is_string($assocData)) {
1221
					$className = $assocData;
1222
				} elseif (isset($assocData['className'])) {
1223
					$className = $assocData['className'];
1224
				}
1225
				$model->$className = new $className();
0 ignored issues
show
Bug introduced by
The variable $className does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1226
				$model->$className->schema();
1227
			}
1228
		}
1229
	}
1230
1231
/**
1232
 * &_prepareAssociationQuery method
1233
 *
1234
 * @param Model $model
1235
 * @param array $queryData
1236
 * @param array $binding
1237
 * @return void
1238
 */
1239
	protected function &_prepareAssociationQuery(Model $model, &$queryData, $binding) {
1240
		$type = $binding['type'];
1241
		$assoc = $binding['model'];
1242
		$assocData = $model->{$type}[$assoc];
1243
		$className = $assocData['className'];
1244
1245
		$linkModel = $model->{$className};
1246
		$external = isset($assocData['external']);
1247
		$queryData = $this->_scrubQueryData($queryData);
1248
1249
		$result = array_merge(array('linkModel' => &$linkModel), compact('type', 'assoc', 'assocData', 'external'));
1250
		return $result;
1251
	}
1252
1253
/**
1254
 * Helper method copied from DboSource::_scrubQueryData()
1255
 *
1256
 * @param array $data
1257
 * @return array
1258
 */
1259 View Code Duplication
	protected function _scrubQueryData($data) {
1260
		static $base = null;
1261
		if ($base === null) {
1262
			$base = array_fill_keys(array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group'), array());
1263
			$base['callbacks'] = null;
1264
		}
1265
		return (array)$data + $base;
1266
	}
1267
1268
/**
1269
 * testGenerateInnerJoinAssociationQuery method
1270
 *
1271
 * @return void
1272
 */
1273
	public function testGenerateInnerJoinAssociationQuery() {
1274
		$db = $this->Dbo->config['database'];
1275
		$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1276
		$test->config['database'] = $db;
1277
1278
		$this->Model = $this->getMock('TestModel9', array('getDataSource'));
1279
		$this->Model->expects($this->any())
1280
			->method('getDataSource')
1281
			->will($this->returnValue($test));
1282
1283
		$this->Model->TestModel8 = $this->getMock('TestModel8', array('getDataSource'));
1284
		$this->Model->TestModel8->expects($this->any())
1285
			->method('getDataSource')
1286
			->will($this->returnValue($test));
1287
1288
		$testModel8Table = $this->Model->TestModel8->getDataSource()->fullTableName($this->Model->TestModel8);
1289
1290
		$test->expects($this->at(0))->method('execute')
1291
			->with($this->stringContains('`TestModel9` LEFT JOIN ' . $testModel8Table));
1292
1293
		$test->expects($this->at(1))->method('execute')
1294
			->with($this->stringContains('TestModel9` INNER JOIN ' . $testModel8Table));
1295
1296
		$test->read($this->Model, array('recursive' => 1));
1297
		$this->Model->belongsTo['TestModel8']['type'] = 'INNER';
1298
		$test->read($this->Model, array('recursive' => 1));
1299
	}
1300
1301
/**
1302
 * testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding method
1303
 *
1304
 * @return void
1305
 */
1306
	public function testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding() {
1307
		$this->Model = new TestModel8();
1308
		$this->Model->schema();
1309
		$this->_buildRelatedModels($this->Model);
1310
1311
		$binding = array('type' => 'hasOne', 'model' => 'TestModel9');
1312
		$queryData = array();
1313
		$resultSet = null;
1314
		$null = null;
1315
1316
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1317
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1318
		$this->assertTrue($result);
1319
1320
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1321
		$this->assertRegExp('/^SELECT\s+`TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`, `TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`\s+/', $result);
1322
		$this->assertRegExp('/FROM\s+\S+`test_model8` AS `TestModel8`\s+LEFT JOIN\s+\S+`test_model9` AS `TestModel9`/', $result);
1323
		$this->assertRegExp('/\s+ON\s+\(`TestModel9`\.`name` != \'mariano\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
1324
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1325
	}
1326
1327
/**
1328
 * testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding method
1329
 *
1330
 * @return void
1331
 */
1332
	public function testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding() {
1333
		$this->Model = new TestModel9();
1334
		$this->Model->schema();
1335
		$this->_buildRelatedModels($this->Model);
1336
1337
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel8');
1338
		$queryData = array();
1339
		$resultSet = null;
1340
		$null = null;
1341
1342
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1343
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1344
		$this->assertTrue($result);
1345
1346
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1347
		$this->assertRegExp('/^SELECT\s+`TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`, `TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`\s+/', $result);
1348
		$this->assertRegExp('/FROM\s+\S+`test_model9` AS `TestModel9`\s+LEFT JOIN\s+\S+`test_model8` AS `TestModel8`/', $result);
1349
		$this->assertRegExp('/\s+ON\s+\(`TestModel8`\.`name` != \'larry\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
1350
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1351
	}
1352
1353
/**
1354
 * testGenerateAssociationQuerySelfJoinWithConditions method
1355
 *
1356
 * @return void
1357
 */
1358
	public function testGenerateAssociationQuerySelfJoinWithConditions() {
1359
		$this->Model = new TestModel4();
1360
		$this->Model->schema();
1361
		$this->_buildRelatedModels($this->Model);
1362
1363
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
1364
		$queryData = array('conditions' => array('TestModel4Parent.name !=' => 'mariano'));
1365
		$resultSet = null;
1366
		$null = null;
1367
1368
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1369
1370
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1371
		$this->assertTrue($result);
1372
1373
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1374
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
1375
		$this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
1376
		$this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
1377
		$this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel4Parent`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1378
1379
		$this->Featured2 = new Featured2();
1380
		$this->Featured2->schema();
1381
1382
		$this->Featured2->bindModel(array(
1383
			'belongsTo' => array(
1384
				'ArticleFeatured2' => array(
1385
					'conditions' => 'ArticleFeatured2.published = \'Y\'',
1386
					'fields' => 'id, title, user_id, published'
1387
				)
1388
			)
1389
		));
1390
1391
		$this->_buildRelatedModels($this->Featured2);
1392
1393
		$binding = array('type' => 'belongsTo', 'model' => 'ArticleFeatured2');
1394
		$queryData = array('conditions' => array());
1395
		$resultSet = null;
1396
		$null = null;
1397
1398
		$params = &$this->_prepareAssociationQuery($this->Featured2, $queryData, $binding);
1399
1400
		$result = $this->Dbo->generateAssociationQuery($this->Featured2, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1401
		$this->assertTrue($result);
1402
		$result = $this->Dbo->generateAssociationQuery($this->Featured2, $null, null, null, null, $queryData, false, $null);
1403
1404
		$this->assertRegExp(
1405
			'/^SELECT\s+`Featured2`\.`id`, `Featured2`\.`article_id`, `Featured2`\.`category_id`, `Featured2`\.`name`,\s+' .
1406
			'`ArticleFeatured2`\.`id`, `ArticleFeatured2`\.`title`, `ArticleFeatured2`\.`user_id`, `ArticleFeatured2`\.`published`\s+' .
1407
			'FROM\s+\S+`featured2` AS `Featured2`\s+LEFT JOIN\s+\S+`article_featured` AS `ArticleFeatured2`' .
1408
			'\s+ON\s+\(`ArticleFeatured2`.`published` = \'Y\'\s+AND\s+`Featured2`\.`article_featured2_id` = `ArticleFeatured2`\.`id`\)' .
1409
			'\s+WHERE\s+1\s+=\s+1\s*$/',
1410
			$result
1411
		);
1412
	}
1413
1414
/**
1415
 * testGenerateAssociationQueryHasOne method
1416
 *
1417
 * @return void
1418
 */
1419 View Code Duplication
	public function testGenerateAssociationQueryHasOne() {
1420
		$this->Model = new TestModel4();
1421
		$this->Model->schema();
1422
		$this->_buildRelatedModels($this->Model);
1423
1424
		$binding = array('type' => 'hasOne', 'model' => 'TestModel5');
1425
1426
		$queryData = array();
1427
		$resultSet = null;
1428
		$null = null;
1429
1430
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1431
1432
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1433
		$this->assertTrue($result);
1434
1435
		$testModel5Table = $this->Dbo->fullTableName($this->Model->TestModel5);
1436
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1437
		$expected = ' LEFT JOIN ' . $testModel5Table . ' AS `TestModel5` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1438
		$this->assertEquals(trim($expected), trim($result));
1439
1440
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1441
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1442
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+/', $result);
1443
		$this->assertRegExp('/`test_model5` AS `TestModel5`\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE/', $result);
1444
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1445
	}
1446
1447
/**
1448
 * testGenerateAssociationQueryHasOneWithConditions method
1449
 *
1450
 * @return void
1451
 */
1452 View Code Duplication
	public function testGenerateAssociationQueryHasOneWithConditions() {
1453
		$this->Model = new TestModel4();
1454
		$this->Model->schema();
1455
		$this->_buildRelatedModels($this->Model);
1456
1457
		$binding = array('type' => 'hasOne', 'model' => 'TestModel5');
1458
1459
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1460
		$resultSet = null;
1461
		$null = null;
1462
1463
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1464
1465
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1466
		$this->assertTrue($result);
1467
1468
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1469
1470
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1471
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model5` AS `TestModel5`/', $result);
1472
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id`\s+=\s+`TestModel4`.`id`\)\s+WHERE/', $result);
1473
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*`TestModel5`.`name`\s+!=\s+\'mariano\'\s*(?:\))?\s*$/', $result);
1474
	}
1475
1476
/**
1477
 * testGenerateAssociationQueryBelongsTo method
1478
 *
1479
 * @return void
1480
 */
1481 View Code Duplication
	public function testGenerateAssociationQueryBelongsTo() {
1482
		$this->Model = new TestModel5();
1483
		$this->Model->schema();
1484
		$this->_buildRelatedModels($this->Model);
1485
1486
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
1487
		$queryData = array();
1488
		$resultSet = null;
1489
		$null = null;
1490
1491
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1492
1493
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1494
		$this->assertTrue($result);
1495
1496
		$testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
1497
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1498
		$expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1499
		$this->assertEquals(trim($expected), trim($result));
1500
1501
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1502
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`, `TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1503
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
1504
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
1505
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1506
	}
1507
1508
/**
1509
 * testGenerateAssociationQueryBelongsToWithConditions method
1510
 *
1511
 * @return void
1512
 */
1513
	public function testGenerateAssociationQueryBelongsToWithConditions() {
1514
		$this->Model = new TestModel5();
1515
		$this->Model->schema();
1516
		$this->_buildRelatedModels($this->Model);
1517
1518
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
1519
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1520
		$resultSet = null;
1521
		$null = null;
1522
1523
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1524
1525
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1526
		$this->assertTrue($result);
1527
1528
		$testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
1529
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1530
		$expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1531
		$this->assertEquals(trim($expected), trim($result));
1532
1533
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1534
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`, `TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1535
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
1536
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
1537
		$this->assertRegExp('/\s+WHERE\s+`TestModel5`.`name` != \'mariano\'\s*$/', $result);
1538
	}
1539
1540
/**
1541
 * testGenerateAssociationQueryHasMany method
1542
 *
1543
 * @return void
1544
 */
1545 View Code Duplication
	public function testGenerateAssociationQueryHasMany() {
1546
		$this->Model = new TestModel5();
1547
		$this->Model->schema();
1548
		$this->_buildRelatedModels($this->Model);
1549
1550
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1551
		$queryData = array();
1552
		$resultSet = null;
1553
		$null = null;
1554
1555
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1556
1557
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1558
1559
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1560
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE/', $result);
1561
		$this->assertRegExp('/\s+WHERE\s+`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)/', $result);
1562
1563
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1564
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1565
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1566
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1567
	}
1568
1569
/**
1570
 * testGenerateAssociationQueryHasManyWithLimit method
1571
 *
1572
 * @return void
1573
 */
1574
	public function testGenerateAssociationQueryHasManyWithLimit() {
1575
		$this->Model = new TestModel5();
1576
		$this->Model->schema();
1577
		$this->_buildRelatedModels($this->Model);
1578
1579
		$this->Model->hasMany['TestModel6']['limit'] = 2;
1580
1581
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1582
		$queryData = array();
1583
		$resultSet = null;
1584
		$null = null;
1585
1586
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1587
1588
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1589
		$this->assertRegExp(
1590
			'/^SELECT\s+' .
1591
			'`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+' .
1592
			'FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+' .
1593
			'`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)\s*' .
1594
			'LIMIT \d*' .
1595
			'\s*$/', $result
1596
		);
1597
1598
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1599
		$this->assertRegExp(
1600
			'/^SELECT\s+' .
1601
			'`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+' .
1602
			'FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+' .
1603
			'(?:\()?\s*1 = 1\s*(?:\))?' .
1604
			'\s*$/', $result
1605
		);
1606
	}
1607
1608
/**
1609
 * testGenerateAssociationQueryHasManyWithConditions method
1610
 *
1611
 * @return void
1612
 */
1613 View Code Duplication
	public function testGenerateAssociationQueryHasManyWithConditions() {
1614
		$this->Model = new TestModel5();
1615
		$this->Model->schema();
1616
		$this->_buildRelatedModels($this->Model);
1617
1618
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1619
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1620
		$resultSet = null;
1621
		$null = null;
1622
1623
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1624
1625
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1626
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1627
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1628
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1629
1630
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1631
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1632
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1633
		$this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel5`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1634
	}
1635
1636
/**
1637
 * testGenerateAssociationQueryHasManyWithOffsetAndLimit method
1638
 *
1639
 * @return void
1640
 */
1641 View Code Duplication
	public function testGenerateAssociationQueryHasManyWithOffsetAndLimit() {
1642
		$this->Model = new TestModel5();
1643
		$this->Model->schema();
1644
		$this->_buildRelatedModels($this->Model);
1645
1646
		$backup = $this->Model->hasMany['TestModel6'];
1647
1648
		$this->Model->hasMany['TestModel6']['offset'] = 2;
1649
		$this->Model->hasMany['TestModel6']['limit'] = 5;
1650
1651
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1652
		$queryData = array();
1653
		$resultSet = null;
1654
		$null = null;
1655
1656
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1657
1658
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1659
1660
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1661
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1662
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1663
		$this->assertRegExp('/\s+LIMIT 2,\s*5\s*$/', $result);
1664
1665
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1666
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1667
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1668
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1669
1670
		$this->Model->hasMany['TestModel6'] = $backup;
1671
	}
1672
1673
/**
1674
 * testGenerateAssociationQueryHasManyWithPageAndLimit method
1675
 *
1676
 * @return void
1677
 */
1678 View Code Duplication
	public function testGenerateAssociationQueryHasManyWithPageAndLimit() {
1679
		$this->Model = new TestModel5();
1680
		$this->Model->schema();
1681
		$this->_buildRelatedModels($this->Model);
1682
1683
		$backup = $this->Model->hasMany['TestModel6'];
1684
1685
		$this->Model->hasMany['TestModel6']['page'] = 2;
1686
		$this->Model->hasMany['TestModel6']['limit'] = 5;
1687
1688
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1689
		$queryData = array();
1690
		$resultSet = null;
1691
		$null = null;
1692
1693
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1694
1695
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1696
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1697
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1698
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1699
		$this->assertRegExp('/\s+LIMIT 5,\s*5\s*$/', $result);
1700
1701
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1702
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1703
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1704
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1705
1706
		$this->Model->hasMany['TestModel6'] = $backup;
1707
	}
1708
1709
/**
1710
 * testGenerateAssociationQueryHasManyWithFields method
1711
 *
1712
 * @return void
1713
 */
1714
	public function testGenerateAssociationQueryHasManyWithFields() {
1715
		$this->Model = new TestModel5();
1716
		$this->Model->schema();
1717
		$this->_buildRelatedModels($this->Model);
1718
1719
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1720
		$queryData = array('fields' => array('`TestModel5`.`name`'));
1721
		$resultSet = null;
1722
		$null = null;
1723
1724
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1725
1726
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1727
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1728
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1729
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1730
1731
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1732
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`id`\s+/', $result);
1733
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1734
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1735
1736
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1737
		$queryData = array('fields' => array('`TestModel5`.`id`, `TestModel5`.`name`'));
1738
		$resultSet = null;
1739
		$null = null;
1740
1741
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1742
1743
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1744
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1745
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1746
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1747
1748
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1749
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1750
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1751
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1752
1753
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1754
		$queryData = array('fields' => array('`TestModel5`.`name`', '`TestModel5`.`created`'));
1755
		$resultSet = null;
1756
		$null = null;
1757
1758
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1759
1760
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1761
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1762
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1763
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1764
1765
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1766
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`id`\s+/', $result);
1767
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1768
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1769
1770
		$this->Model->hasMany['TestModel6']['fields'] = array('name');
1771
1772
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1773
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1774
		$resultSet = null;
1775
		$null = null;
1776
1777
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1778
1779
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1780
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
1781
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1782
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1783
1784
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1785
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1786
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1787
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1788
1789
		unset($this->Model->hasMany['TestModel6']['fields']);
1790
1791
		$this->Model->hasMany['TestModel6']['fields'] = array('id', 'name');
1792
1793
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1794
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1795
		$resultSet = null;
1796
		$null = null;
1797
1798
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1799
1800
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1801
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
1802
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1803
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1804
1805
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1806
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1807
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1808
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1809
1810
		unset($this->Model->hasMany['TestModel6']['fields']);
1811
1812
		$this->Model->hasMany['TestModel6']['fields'] = array('test_model5_id', 'name');
1813
1814
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1815
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1816
		$resultSet = null;
1817
		$null = null;
1818
1819
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1820
1821
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1822
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`test_model5_id`, `TestModel6`\.`name`\s+/', $result);
1823
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1824
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1825
1826
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1827
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1828
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1829
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1830
1831
		unset($this->Model->hasMany['TestModel6']['fields']);
1832
	}
1833
1834
/**
1835
 * test generateAssociationQuery with a hasMany and an aggregate function.
1836
 *
1837
 * @return void
1838
 */
1839
	public function testGenerateAssociationQueryHasManyAndAggregateFunction() {
1840
		$this->Model = new TestModel5();
1841
		$this->Model->schema();
1842
		$this->_buildRelatedModels($this->Model);
1843
1844
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1845
		$queryData = array('fields' => array('MIN(`TestModel5`.`test_model4_id`)'));
1846
		$resultSet = null;
1847
		$null = null;
1848
1849
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1850
		$this->Model->recursive = 0;
1851
1852
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, $params['type'], $params['assoc'], $params['assocData'], $queryData, false, $resultSet);
1853
		$this->assertRegExp('/^SELECT\s+MIN\(`TestModel5`\.`test_model4_id`\)\s+FROM/', $result);
1854
	}
1855
1856
/**
1857
 * testGenerateAssociationQueryHasAndBelongsToMany method
1858
 *
1859
 * @return void
1860
 */
1861
	public function testGenerateAssociationQueryHasAndBelongsToMany() {
1862
		$this->Model = new TestModel4();
1863
		$this->Model->schema();
1864
		$this->_buildRelatedModels($this->Model);
1865
1866
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1867
		$queryData = array();
1868
		$resultSet = null;
1869
		$null = null;
1870
1871
		$params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1872
1873
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1874
		$assocTable = $this->Dbo->fullTableName($this->Model->TestModel4TestModel7, true, true);
1875
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1876
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7` AS `TestModel7`\s+JOIN\s+' . $assocTable . '/', $result);
1877
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+AND/', $result);
1878
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)/', $result);
1879
		$this->assertRegExp('/WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
1880
1881
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1882
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1883
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE/', $result);
1884
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
1885
	}
1886
1887
/**
1888
 * testGenerateAssociationQueryHasAndBelongsToManyWithConditions method
1889
 *
1890
 * @return void
1891
 */
1892 View Code Duplication
	public function testGenerateAssociationQueryHasAndBelongsToManyWithConditions() {
1893
		$this->Model = new TestModel4();
1894
		$this->Model->schema();
1895
		$this->_buildRelatedModels($this->Model);
1896
1897
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1898
		$queryData = array('conditions' => array('TestModel4.name !=' => 'mariano'));
1899
		$resultSet = null;
1900
		$null = null;
1901
1902
		$params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1903
1904
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1905
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1906
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
1907
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
1908
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
1909
1910
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1911
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1912
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?`TestModel4`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1913
	}
1914
1915
/**
1916
 * testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit method
1917
 *
1918
 * @return void
1919
 */
1920 View Code Duplication
	public function testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit() {
1921
		$this->Model = new TestModel4();
1922
		$this->Model->schema();
1923
		$this->_buildRelatedModels($this->Model);
1924
1925
		$backup = $this->Model->hasAndBelongsToMany['TestModel7'];
1926
1927
		$this->Model->hasAndBelongsToMany['TestModel7']['offset'] = 2;
1928
		$this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
1929
1930
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1931
		$queryData = array();
1932
		$resultSet = null;
1933
		$null = null;
1934
1935
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1936
1937
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1938
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1939
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
1940
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+/', $result);
1941
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
1942
		$this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 2,\s*5\s*$/', $result);
1943
1944
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1945
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1946
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1947
1948
		$this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
1949
	}
1950
1951
/**
1952
 * testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit method
1953
 *
1954
 * @return void
1955
 */
1956 View Code Duplication
	public function testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit() {
1957
		$this->Model = new TestModel4();
1958
		$this->Model->schema();
1959
		$this->_buildRelatedModels($this->Model);
1960
1961
		$backup = $this->Model->hasAndBelongsToMany['TestModel7'];
1962
1963
		$this->Model->hasAndBelongsToMany['TestModel7']['page'] = 2;
1964
		$this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
1965
1966
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1967
		$queryData = array();
1968
		$resultSet = null;
1969
		$null = null;
1970
1971
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1972
1973
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
1974
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1975
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
1976
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
1977
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
1978
		$this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 5,\s*5\s*$/', $result);
1979
1980
		$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
1981
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1982
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1983
1984
		$this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
1985
	}
1986
1987
/**
1988
 * testSelectDistict method
1989
 *
1990
 * @return void
1991
 */
1992
	public function testSelectDistict() {
1993
		$this->Model = new TestModel4();
1994
		$result = $this->Dbo->fields($this->Model, 'Vendor', "DISTINCT Vendor.id, Vendor.name");
1995
		$expected = array('DISTINCT `Vendor`.`id`', '`Vendor`.`name`');
1996
		$this->assertEquals($expected, $result);
1997
	}
1998
1999
/**
2000
 * testStringConditionsParsing method
2001
 *
2002
 * @return void
2003
 */
2004
	public function testStringConditionsParsing() {
2005
		$result = $this->Dbo->conditions("ProjectBid.project_id = Project.id");
2006
		$expected = " WHERE `ProjectBid`.`project_id` = `Project`.`id`";
2007
		$this->assertEquals($expected, $result);
2008
2009
		$result = $this->Dbo->conditions("Candy.name LIKE 'a' AND HardCandy.name LIKE 'c'");
2010
		$expected = " WHERE `Candy`.`name` LIKE 'a' AND `HardCandy`.`name` LIKE 'c'";
2011
		$this->assertEquals($expected, $result);
2012
2013
		$result = $this->Dbo->conditions("HardCandy.name LIKE 'a' AND Candy.name LIKE 'c'");
2014
		$expected = " WHERE `HardCandy`.`name` LIKE 'a' AND `Candy`.`name` LIKE 'c'";
2015
		$this->assertEquals($expected, $result);
2016
2017
		$result = $this->Dbo->conditions("Post.title = '1.1'");
2018
		$expected = " WHERE `Post`.`title` = '1.1'";
2019
		$this->assertEquals($expected, $result);
2020
2021
		$result = $this->Dbo->conditions("User.id != 0 AND User.user LIKE '%arr%'");
2022
		$expected = " WHERE `User`.`id` != 0 AND `User`.`user` LIKE '%arr%'";
2023
		$this->assertEquals($expected, $result);
2024
2025
		$result = $this->Dbo->conditions("SUM(Post.comments_count) > 500");
2026
		$expected = " WHERE SUM(`Post`.`comments_count`) > 500";
2027
		$this->assertEquals($expected, $result);
2028
2029
		$result = $this->Dbo->conditions("(Post.created < '" . date('Y-m-d H:i') . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
2030
		$expected = " WHERE (`Post`.`created` < '" . date('Y-m-d H:i') . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
2031
		$this->assertEquals($expected, $result);
2032
2033
		$result = $this->Dbo->conditions("score BETWEEN 90.1 AND 95.7");
2034
		$expected = " WHERE score BETWEEN 90.1 AND 95.7";
2035
		$this->assertEquals($expected, $result);
2036
2037
		$result = $this->Dbo->conditions(array('score' => array(2 => 1, 2, 10)));
2038
		$expected = " WHERE `score` IN (1, 2, 10)";
2039
		$this->assertEquals($expected, $result);
2040
2041
		$result = $this->Dbo->conditions("Aro.rght = Aro.lft + 1.1");
2042
		$expected = " WHERE `Aro`.`rght` = `Aro`.`lft` + 1.1";
2043
		$this->assertEquals($expected, $result);
2044
2045
		$result = $this->Dbo->conditions("(Post.created < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
2046
		$expected = " WHERE (`Post`.`created` < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
2047
		$this->assertEquals($expected, $result);
2048
2049
		$result = $this->Dbo->conditions('Sportstaette.sportstaette LIKE "%ru%" AND Sportstaette.sportstaettenart_id = 2');
2050
		$expected = ' WHERE `Sportstaette`.`sportstaette` LIKE "%ru%" AND `Sportstaette`.`sportstaettenart_id` = 2';
2051
		$this->assertRegExp('/\s*WHERE\s+`Sportstaette`\.`sportstaette`\s+LIKE\s+"%ru%"\s+AND\s+`Sports/', $result);
2052
		$this->assertEquals($expected, $result);
2053
2054
		$result = $this->Dbo->conditions('Sportstaette.sportstaettenart_id = 2 AND Sportstaette.sportstaette LIKE "%ru%"');
2055
		$expected = ' WHERE `Sportstaette`.`sportstaettenart_id` = 2 AND `Sportstaette`.`sportstaette` LIKE "%ru%"';
2056
		$this->assertEquals($expected, $result);
2057
2058
		$result = $this->Dbo->conditions('SUM(Post.comments_count) > 500 AND NOT Post.title IS NULL AND NOT Post.extended_title IS NULL');
2059
		$expected = ' WHERE SUM(`Post`.`comments_count`) > 500 AND NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL';
2060
		$this->assertEquals($expected, $result);
2061
2062
		$result = $this->Dbo->conditions('NOT Post.title IS NULL AND NOT Post.extended_title IS NULL AND SUM(Post.comments_count) > 500');
2063
		$expected = ' WHERE NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL AND SUM(`Post`.`comments_count`) > 500';
2064
		$this->assertEquals($expected, $result);
2065
2066
		$result = $this->Dbo->conditions('NOT Post.extended_title IS NULL AND NOT Post.title IS NULL AND Post.title != "" AND SPOON(SUM(Post.comments_count) + 1.1) > 500');
2067
		$expected = ' WHERE NOT `Post`.`extended_title` IS NULL AND NOT `Post`.`title` IS NULL AND `Post`.`title` != "" AND SPOON(SUM(`Post`.`comments_count`) + 1.1) > 500';
2068
		$this->assertEquals($expected, $result);
2069
2070
		$result = $this->Dbo->conditions('NOT Post.title_extended IS NULL AND NOT Post.title IS NULL AND Post.title_extended != Post.title');
2071
		$expected = ' WHERE NOT `Post`.`title_extended` IS NULL AND NOT `Post`.`title` IS NULL AND `Post`.`title_extended` != `Post`.`title`';
2072
		$this->assertEquals($expected, $result);
2073
2074
		$result = $this->Dbo->conditions("Comment.id = 'a'");
2075
		$expected = " WHERE `Comment`.`id` = 'a'";
2076
		$this->assertEquals($expected, $result);
2077
2078
		$result = $this->Dbo->conditions("lower(Article.title) LIKE 'a%'");
2079
		$expected = " WHERE lower(`Article`.`title`) LIKE 'a%'";
2080
		$this->assertEquals($expected, $result);
2081
2082
		$result = $this->Dbo->conditions('((MATCH(Video.title) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 2) + (MATCH(Video.description) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 0.4) + (MATCH(Video.tags) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 1.5))');
2083
		$expected = ' WHERE ((MATCH(`Video`.`title`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 2) + (MATCH(`Video`.`description`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 0.4) + (MATCH(`Video`.`tags`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 1.5))';
2084
		$this->assertEquals($expected, $result);
2085
2086
		$result = $this->Dbo->conditions('DATEDIFF(NOW(),Article.published) < 1 && Article.live=1');
2087
		$expected = " WHERE DATEDIFF(NOW(),`Article`.`published`) < 1 && `Article`.`live`=1";
2088
		$this->assertEquals($expected, $result);
2089
2090
		$result = $this->Dbo->conditions('file = "index.html"');
2091
		$expected = ' WHERE file = "index.html"';
2092
		$this->assertEquals($expected, $result);
2093
2094
		$result = $this->Dbo->conditions("file = 'index.html'");
2095
		$expected = " WHERE file = 'index.html'";
2096
		$this->assertEquals($expected, $result);
2097
2098
		$letter = $letter = 'd.a';
2099
		$conditions = array('Company.name like ' => $letter . '%');
2100
		$result = $this->Dbo->conditions($conditions);
2101
		$expected = " WHERE `Company`.`name` like 'd.a%'";
2102
		$this->assertEquals($expected, $result);
2103
2104
		$conditions = array('Artist.name' => 'JUDY and MARY');
2105
		$result = $this->Dbo->conditions($conditions);
2106
		$expected = " WHERE `Artist`.`name` = 'JUDY and MARY'";
2107
		$this->assertEquals($expected, $result);
2108
2109
		$conditions = array('Artist.name' => 'JUDY AND MARY');
2110
		$result = $this->Dbo->conditions($conditions);
2111
		$expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
2112
		$this->assertEquals($expected, $result);
2113
2114
		$conditions = array('Company.name similar to ' => 'a word');
2115
		$result = $this->Dbo->conditions($conditions);
2116
		$expected = " WHERE `Company`.`name` similar to 'a word'";
2117
		$this->assertEquals($expected, $result);
2118
	}
2119
2120
/**
2121
 * testQuotesInStringConditions method
2122
 *
2123
 * @return void
2124
 */
2125
	public function testQuotesInStringConditions() {
2126
		$result = $this->Dbo->conditions('Member.email = \'[email protected]\'');
2127
		$expected = ' WHERE `Member`.`email` = \'[email protected]\'';
2128
		$this->assertEquals($expected, $result);
2129
2130
		$result = $this->Dbo->conditions('Member.email = "[email protected]"');
2131
		$expected = ' WHERE `Member`.`email` = "[email protected]"';
2132
		$this->assertEquals($expected, $result);
2133
2134
		$result = $this->Dbo->conditions('Member.email = \'[email protected]\' AND Member.user LIKE \'mariano.iglesias%\'');
2135
		$expected = ' WHERE `Member`.`email` = \'[email protected]\' AND `Member`.`user` LIKE \'mariano.iglesias%\'';
2136
		$this->assertEquals($expected, $result);
2137
2138
		$result = $this->Dbo->conditions('Member.email = "[email protected]" AND Member.user LIKE "mariano.iglesias%"');
2139
		$expected = ' WHERE `Member`.`email` = "[email protected]" AND `Member`.`user` LIKE "mariano.iglesias%"';
2140
		$this->assertEquals($expected, $result);
2141
	}
2142
2143
/**
2144
 * test that - in conditions and field names works
2145
 *
2146
 * @return void
2147
 */
2148
	public function testHypenInStringConditionsAndFieldNames() {
2149
		$result = $this->Dbo->conditions('I18n__title_pt-br.content = "test"');
2150
		$this->assertEquals(' WHERE `I18n__title_pt-br`.`content` = "test"', $result);
2151
2152
		$result = $this->Dbo->conditions('Model.field=NOW()-3600');
2153
		$this->assertEquals(' WHERE `Model`.`field`=NOW()-3600', $result);
2154
2155
		$result = $this->Dbo->conditions('NOW() - Model.created < 7200');
2156
		$this->assertEquals(' WHERE NOW() - `Model`.`created` < 7200', $result);
2157
2158
		$result = $this->Dbo->conditions('NOW()-Model.created < 7200');
2159
		$this->assertEquals(' WHERE NOW()-`Model`.`created` < 7200', $result);
2160
	}
2161
2162
/**
2163
 * testParenthesisInStringConditions method
2164
 *
2165
 * @return void
2166
 */
2167
	public function testParenthesisInStringConditions() {
2168
		$result = $this->Dbo->conditions('Member.name = \'(lu\'');
2169
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
2170
2171
		$result = $this->Dbo->conditions('Member.name = \')lu\'');
2172
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
2173
2174
		$result = $this->Dbo->conditions('Member.name = \'va(lu\'');
2175
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
2176
2177
		$result = $this->Dbo->conditions('Member.name = \'va)lu\'');
2178
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
2179
2180
		$result = $this->Dbo->conditions('Member.name = \'va(lu)\'');
2181
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
2182
2183
		$result = $this->Dbo->conditions('Member.name = \'va(lu)e\'');
2184
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
2185
2186
		$result = $this->Dbo->conditions('Member.name = \'(mariano)\'');
2187
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
2188
2189
		$result = $this->Dbo->conditions('Member.name = \'(mariano)iglesias\'');
2190
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
2191
2192
		$result = $this->Dbo->conditions('Member.name = \'(mariano) iglesias\'');
2193
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
2194
2195
		$result = $this->Dbo->conditions('Member.name = \'(mariano word) iglesias\'');
2196
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
2197
2198
		$result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias)\'');
2199
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
2200
2201
		$result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias)\'');
2202
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
2203
2204
		$result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias) CakePHP\'');
2205
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
2206
2207
		$result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias) CakePHP\'');
2208
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
2209
	}
2210
2211
/**
2212
 * testParenthesisInArrayConditions method
2213
 *
2214
 * @return void
2215
 */
2216
	public function testParenthesisInArrayConditions() {
2217
		$result = $this->Dbo->conditions(array('Member.name' => '(lu'));
2218
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
2219
2220
		$result = $this->Dbo->conditions(array('Member.name' => ')lu'));
2221
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
2222
2223
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu'));
2224
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
2225
2226
		$result = $this->Dbo->conditions(array('Member.name' => 'va)lu'));
2227
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
2228
2229
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu)'));
2230
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
2231
2232
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu)e'));
2233
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
2234
2235
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano)'));
2236
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
2237
2238
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano)iglesias'));
2239
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
2240
2241
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano) iglesias'));
2242
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
2243
2244
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano word) iglesias'));
2245
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
2246
2247
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias)'));
2248
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
2249
2250
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias)'));
2251
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
2252
2253
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias) CakePHP'));
2254
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
2255
2256
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias) CakePHP'));
2257
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
2258
	}
2259
2260
/**
2261
 * testArrayConditionsParsing method
2262
 *
2263
 * @return void
2264
 */
2265
	public function testArrayConditionsParsing() {
2266
		$this->loadFixtures('Post', 'Author');
2267
		$result = $this->Dbo->conditions(array('Stereo.type' => 'in dash speakers'));
2268
		$this->assertRegExp("/^\s+WHERE\s+`Stereo`.`type`\s+=\s+'in dash speakers'/", $result);
2269
2270
		$result = $this->Dbo->conditions(array('Candy.name LIKE' => 'a', 'HardCandy.name LIKE' => 'c'));
2271
		$this->assertRegExp("/^\s+WHERE\s+`Candy`.`name` LIKE\s+'a'\s+AND\s+`HardCandy`.`name`\s+LIKE\s+'c'/", $result);
2272
2273
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a', 'Candy.name LIKE' => 'c'));
2274
		$expected = " WHERE `HardCandy`.`name` LIKE 'a' AND `Candy`.`name` LIKE 'c'";
2275
		$this->assertEquals($expected, $result);
2276
2277
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a%', 'Candy.name LIKE' => '%c%'));
2278
		$expected = " WHERE `HardCandy`.`name` LIKE 'a%' AND `Candy`.`name` LIKE '%c%'";
2279
		$this->assertEquals($expected, $result);
2280
2281
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'to be or%', 'Candy.name LIKE' => '%not to be%'));
2282
		$expected = " WHERE `HardCandy`.`name` LIKE 'to be or%' AND `Candy`.`name` LIKE '%not to be%'";
2283
		$this->assertEquals($expected, $result);
2284
2285
		$result = $this->Dbo->conditions(array(
2286
			"Person.name || ' ' || Person.surname ILIKE" => '%mark%'
2287
		));
2288
		$expected = " WHERE `Person`.`name` || ' ' || `Person`.`surname` ILIKE '%mark%'";
2289
		$this->assertEquals($expected, $result);
2290
2291
		$result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
2292
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2293
		$this->assertEquals($expected, $result);
2294
2295
		$result = $this->Dbo->conditions(array('Post.title' => 1.1));
2296
		$expected = " WHERE `Post`.`title` = 1.1";
2297
		$this->assertEquals($expected, $result);
2298
2299
		$result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
2300
		$expected = " WHERE `Post`.`title` = '1.1'";
2301
		$this->assertEquals($expected, $result);
2302
2303
		$result = $this->Dbo->conditions(array('SUM(Post.comments_count) >' => '500'));
2304
		$expected = " WHERE SUM(`Post`.`comments_count`) > '500'";
2305
		$this->assertEquals($expected, $result);
2306
2307
		$result = $this->Dbo->conditions(array('MAX(Post.rating) >' => '50'));
2308
		$expected = " WHERE MAX(`Post`.`rating`) > '50'";
2309
		$this->assertEquals($expected, $result);
2310
2311
		$result = $this->Dbo->conditions(array('lower(Article.title)' => 'secrets'));
2312
		$expected = " WHERE lower(`Article`.`title`) = 'secrets'";
2313
		$this->assertEquals($expected, $result);
2314
2315
		$result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
2316
		$expected = " WHERE `title` LIKE '%hello'";
2317
		$this->assertEquals($expected, $result);
2318
2319
		$result = $this->Dbo->conditions(array('Post.name' => 'mad(g)ik'));
2320
		$expected = " WHERE `Post`.`name` = 'mad(g)ik'";
2321
		$this->assertEquals($expected, $result);
2322
2323
		$result = $this->Dbo->conditions(array('score' => array(1, 2, 10)));
2324
		$expected = " WHERE `score` IN (1, 2, 10)";
2325
		$this->assertEquals($expected, $result);
2326
2327
		$result = $this->Dbo->conditions(array('score' => array()));
2328
		$expected = " WHERE `score` IS NULL";
2329
		$this->assertEquals($expected, $result);
2330
2331
		$result = $this->Dbo->conditions(array('score !=' => array()));
2332
		$expected = " WHERE `score` IS NOT NULL";
2333
		$this->assertEquals($expected, $result);
2334
2335
		$result = $this->Dbo->conditions(array('score !=' => '20'));
2336
		$expected = " WHERE `score` != '20'";
2337
		$this->assertEquals($expected, $result);
2338
2339
		$result = $this->Dbo->conditions(array('score >' => '20'));
2340
		$expected = " WHERE `score` > '20'";
2341
		$this->assertEquals($expected, $result);
2342
2343
		$result = $this->Dbo->conditions(array('client_id >' => '20'), true, true, new TestModel());
2344
		$expected = " WHERE `client_id` > 20";
2345
		$this->assertEquals($expected, $result);
2346
2347
		$result = $this->Dbo->conditions(array('OR' => array(
2348
			array('User.user' => 'mariano'),
2349
			array('User.user' => 'nate')
2350
		)));
2351
2352
		$expected = " WHERE ((`User`.`user` = 'mariano') OR (`User`.`user` = 'nate'))";
2353
		$this->assertEquals($expected, $result);
2354
2355
		$result = $this->Dbo->conditions(array('or' => array(
2356
			'score BETWEEN ? AND ?' => array('4', '5'), 'rating >' => '20'
2357
		)));
2358
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`rating` > '20'))";
2359
		$this->assertEquals($expected, $result);
2360
2361
		$result = $this->Dbo->conditions(array('or' => array(
2362
			'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
2363
		)));
2364
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`score` > '20'))";
2365
		$this->assertEquals($expected, $result);
2366
2367
		$result = $this->Dbo->conditions(array('and' => array(
2368
			'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
2369
		)));
2370
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') AND (`score` > '20'))";
2371
		$this->assertEquals($expected, $result);
2372
2373
		$result = $this->Dbo->conditions(array(
2374
			'published' => 1, 'or' => array('score >' => '2', array('score >' => '20'))
2375
		));
2376
		$expected = " WHERE `published` = 1 AND ((`score` > '2') OR (`score` > '20'))";
2377
		$this->assertEquals($expected, $result);
2378
2379
		$result = $this->Dbo->conditions(array(array('Project.removed' => false)));
2380
		$expected = " WHERE `Project`.`removed` = '0'";
2381
		$this->assertEquals($expected, $result);
2382
2383
		$result = $this->Dbo->conditions(array(array('Project.removed' => true)));
2384
		$expected = " WHERE `Project`.`removed` = '1'";
2385
		$this->assertEquals($expected, $result);
2386
2387
		$result = $this->Dbo->conditions(array(array('Project.removed' => null)));
2388
		$expected = " WHERE `Project`.`removed` IS NULL";
2389
		$this->assertEquals($expected, $result);
2390
2391
		$result = $this->Dbo->conditions(array(array('Project.removed !=' => null)));
2392
		$expected = " WHERE `Project`.`removed` IS NOT NULL";
2393
		$this->assertEquals($expected, $result);
2394
2395
		$result = $this->Dbo->conditions(array('(Usergroup.permissions) & 4' => 4));
2396
		$expected = " WHERE (`Usergroup`.`permissions`) & 4 = 4";
2397
		$this->assertEquals($expected, $result);
2398
2399
		$result = $this->Dbo->conditions(array('((Usergroup.permissions) & 4)' => 4));
2400
		$expected = " WHERE ((`Usergroup`.`permissions`) & 4) = 4";
2401
		$this->assertEquals($expected, $result);
2402
2403
		$result = $this->Dbo->conditions(array('Post.modified >=' => 'DATE_SUB(NOW(), INTERVAL 7 DAY)'));
2404
		$expected = " WHERE `Post`.`modified` >= 'DATE_SUB(NOW(), INTERVAL 7 DAY)'";
2405
		$this->assertEquals($expected, $result);
2406
2407
		$result = $this->Dbo->conditions(array('Post.modified >= DATE_SUB(NOW(), INTERVAL 7 DAY)'));
2408
		$expected = " WHERE `Post`.`modified` >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
2409
		$this->assertEquals($expected, $result);
2410
2411
		$result = $this->Dbo->conditions(array(
2412
			'NOT' => array('Course.id' => null, 'Course.vet' => 'N', 'level_of_education_id' => array(912, 999)),
2413
			'Enrollment.yearcompleted >' => '0')
2414
		);
2415
		$this->assertRegExp('/^\s*WHERE\s+\(NOT\s+\(`Course`\.`id` IS NULL\)\s+AND NOT\s+\(`Course`\.`vet`\s+=\s+\'N\'\)\s+AND NOT\s+\(`level_of_education_id` IN \(912, 999\)\)\)\s+AND\s+`Enrollment`\.`yearcompleted`\s+>\s+\'0\'\s*$/', $result);
2416
2417
		$result = $this->Dbo->conditions(array('id <>' => '8'));
2418
		$this->assertRegExp('/^\s*WHERE\s+`id`\s+<>\s+\'8\'\s*$/', $result);
2419
2420
		$result = $this->Dbo->conditions(array('TestModel.field =' => 'gribe$@()lu'));
2421
		$expected = " WHERE `TestModel`.`field` = 'gribe$@()lu'";
2422
		$this->assertEquals($expected, $result);
2423
2424
		$conditions['NOT'] = array('Listing.expiration BETWEEN ? AND ?' => array("1", "100"));
0 ignored issues
show
Coding Style Comprehensibility introduced by
$conditions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $conditions = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2425
		$conditions[0]['OR'] = array(
2426
			"Listing.title LIKE" => "%term%",
2427
			"Listing.description LIKE" => "%term%"
2428
		);
2429
		$conditions[1]['OR'] = array(
2430
			"Listing.title LIKE" => "%term_2%",
2431
			"Listing.description LIKE" => "%term_2%"
2432
		);
2433
		$result = $this->Dbo->conditions($conditions);
2434
		$expected = " WHERE NOT (`Listing`.`expiration` BETWEEN '1' AND '100') AND" .
2435
		" ((`Listing`.`title` LIKE '%term%') OR (`Listing`.`description` LIKE '%term%')) AND" .
2436
		" ((`Listing`.`title` LIKE '%term_2%') OR (`Listing`.`description` LIKE '%term_2%'))";
2437
		$this->assertEquals($expected, $result);
2438
2439
		$result = $this->Dbo->conditions(array('MD5(CONCAT(Reg.email,Reg.id))' => 'blah'));
2440
		$expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) = 'blah'";
2441
		$this->assertEquals($expected, $result);
2442
2443
		$result = $this->Dbo->conditions(array(
2444
			'MD5(CONCAT(Reg.email,Reg.id))' => array('blah', 'blahblah')
2445
		));
2446
		$expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) IN ('blah', 'blahblah')";
2447
		$this->assertEquals($expected, $result);
2448
2449
		$conditions = array('id' => array(2, 5, 6, 9, 12, 45, 78, 43, 76));
2450
		$result = $this->Dbo->conditions($conditions);
2451
		$expected = " WHERE `id` IN (2, 5, 6, 9, 12, 45, 78, 43, 76)";
2452
		$this->assertEquals($expected, $result);
2453
2454
		$conditions = array('`Correction`.`source` collate utf8_bin' => array('kiwi', 'pear'));
2455
		$result = $this->Dbo->conditions($conditions);
2456
		$expected = " WHERE `Correction`.`source` collate utf8_bin IN ('kiwi', 'pear')";
2457
		$this->assertEquals($expected, $result);
2458
2459
		$conditions = array('title' => 'user(s)');
2460
		$result = $this->Dbo->conditions($conditions);
2461
		$expected = " WHERE `title` = 'user(s)'";
2462
		$this->assertEquals($expected, $result);
2463
2464
		$conditions = array('title' => 'user(s) data');
2465
		$result = $this->Dbo->conditions($conditions);
2466
		$expected = " WHERE `title` = 'user(s) data'";
2467
		$this->assertEquals($expected, $result);
2468
2469
		$conditions = array('title' => 'user(s,arg) data');
2470
		$result = $this->Dbo->conditions($conditions);
2471
		$expected = " WHERE `title` = 'user(s,arg) data'";
2472
		$this->assertEquals($expected, $result);
2473
2474
		$result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM)'));
2475
		$expected = " WHERE `Book`.`book_name` = 'Java(TM)'";
2476
		$this->assertEquals($expected, $result);
2477
2478
		$result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM) '));
2479
		$expected = " WHERE `Book`.`book_name` = 'Java(TM) '";
2480
		$this->assertEquals($expected, $result);
2481
2482
		$result = $this->Dbo->conditions(array("Book.id" => 0));
2483
		$expected = " WHERE `Book`.`id` = 0";
2484
		$this->assertEquals($expected, $result);
2485
2486
		$result = $this->Dbo->conditions(array("Book.id" => null));
2487
		$expected = " WHERE `Book`.`id` IS NULL";
2488
		$this->assertEquals($expected, $result);
2489
2490
		$conditions = array('MysqlModel.id' => '');
2491
		$result = $this->Dbo->conditions($conditions, true, true, $this->model);
2492
		$expected = " WHERE `MysqlModel`.`id` IS NULL";
2493
		$this->assertEquals($expected, $result);
2494
2495
		$result = $this->Dbo->conditions(array('Listing.beds >=' => 0));
2496
		$expected = " WHERE `Listing`.`beds` >= 0";
2497
		$this->assertEquals($expected, $result);
2498
2499
		$result = $this->Dbo->conditions(array(
2500
			'ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN ? AND ?' => array(65, 90)
2501
		));
2502
		$expected = ' WHERE ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN 65 AND 90';
2503
		$this->assertEquals($expected, $result);
2504
2505
		$result = $this->Dbo->conditions(array('or' => array(
2506
			'? BETWEEN Model.field1 AND Model.field2' => '2009-03-04'
2507
		)));
2508
		$expected = " WHERE '2009-03-04' BETWEEN Model.field1 AND Model.field2";
2509
		$this->assertEquals($expected, $result);
2510
	}
2511
2512
/**
2513
 * test conditions() with replacements.
2514
 *
2515
 * @return void
2516
 */
2517
	public function testConditionsWithReplacements() {
2518
		$result = $this->Dbo->conditions(array(
2519
			'score BETWEEN :0 AND :1' => array(90.1, 95.7)
2520
		));
2521
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2522
		$this->assertEquals($expected, $result);
2523
2524
		$result = $this->Dbo->conditions(array(
2525
			'score BETWEEN ? AND ?' => array(90.1, 95.7)
2526
		));
2527
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2528
		$this->assertEquals($expected, $result);
2529
	}
2530
2531
/**
2532
 * Test that array conditions with only one element work.
2533
 *
2534
 * @return void
2535
 */
2536
	public function testArrayConditionsOneElement() {
2537
		$conditions = array('id' => array(1));
2538
		$result = $this->Dbo->conditions($conditions);
2539
		$expected = " WHERE id = (1)";
2540
		$this->assertEquals($expected, $result);
2541
2542
		$conditions = array('id NOT' => array(1));
2543
		$result = $this->Dbo->conditions($conditions);
2544
		$expected = " WHERE NOT (id = (1))";
2545
		$this->assertEquals($expected, $result);
2546
	}
2547
2548
/**
2549
 * testArrayConditionsParsingComplexKeys method
2550
 *
2551
 * @return void
2552
 */
2553
	public function testArrayConditionsParsingComplexKeys() {
2554
		$result = $this->Dbo->conditions(array(
2555
			'CAST(Book.created AS DATE)' => '2008-08-02'
2556
		));
2557
		$expected = " WHERE CAST(`Book`.`created` AS DATE) = '2008-08-02'";
2558
		$this->assertEquals($expected, $result);
2559
2560
		$result = $this->Dbo->conditions(array(
2561
			'CAST(Book.created AS DATE) <=' => '2008-08-02'
2562
		));
2563
		$expected = " WHERE CAST(`Book`.`created` AS DATE) <= '2008-08-02'";
2564
		$this->assertEquals($expected, $result);
2565
2566
		$result = $this->Dbo->conditions(array(
2567
			'(Stats.clicks * 100) / Stats.views >' => 50
2568
		));
2569
		$expected = " WHERE (`Stats`.`clicks` * 100) / `Stats`.`views` > 50";
2570
		$this->assertEquals($expected, $result);
2571
	}
2572
2573
/**
2574
 * testMixedConditionsParsing method
2575
 *
2576
 * @return void
2577
 */
2578
	public function testMixedConditionsParsing() {
2579
		$conditions[] = 'User.first_name = \'Firstname\'';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$conditions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $conditions = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2580
		$conditions[] = array('User.last_name' => 'Lastname');
2581
		$result = $this->Dbo->conditions($conditions);
2582
		$expected = " WHERE `User`.`first_name` = 'Firstname' AND `User`.`last_name` = 'Lastname'";
2583
		$this->assertEquals($expected, $result);
2584
2585
		$conditions = array(
2586
			'Thread.project_id' => 5,
2587
			'Thread.buyer_id' => 14,
2588
			'1=1 GROUP BY Thread.project_id'
2589
		);
2590
		$result = $this->Dbo->conditions($conditions);
2591
		$this->assertRegExp('/^\s*WHERE\s+`Thread`.`project_id`\s*=\s*5\s+AND\s+`Thread`.`buyer_id`\s*=\s*14\s+AND\s+1\s*=\s*1\s+GROUP BY `Thread`.`project_id`$/', $result);
2592
	}
2593
2594
/**
2595
 * testConditionsOptionalArguments method
2596
 *
2597
 * @return void
2598
 */
2599
	public function testConditionsOptionalArguments() {
2600
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano'), true, false);
2601
		$this->assertRegExp('/^\s*`Member`.`name`\s*=\s*\'Mariano\'\s*$/', $result);
2602
2603
		$result = $this->Dbo->conditions(array(), true, false);
2604
		$this->assertRegExp('/^\s*1\s*=\s*1\s*$/', $result);
2605
	}
2606
2607
/**
2608
 * testConditionsWithModel
2609
 *
2610
 * @return void
2611
 */
2612
	public function testConditionsWithModel() {
2613
		$this->Model = new Article2();
2614
2615
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => 0), true, true, $this->Model);
2616
		$expected = " WHERE `Article2`.`viewed` >= 0";
2617
		$this->assertEquals($expected, $result);
2618
2619
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => '0'), true, true, $this->Model);
2620
		$expected = " WHERE `Article2`.`viewed` >= 0";
2621
		$this->assertEquals($expected, $result);
2622
2623
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => '1'), true, true, $this->Model);
2624
		$expected = " WHERE `Article2`.`viewed` >= 1";
2625
		$this->assertEquals($expected, $result);
2626
2627
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array(0, 10)), true, true, $this->Model);
2628
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
2629
		$this->assertEquals($expected, $result);
2630
2631
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('0', '10')), true, true, $this->Model);
2632
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
2633
		$this->assertEquals($expected, $result);
2634
2635
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('1', '10')), true, true, $this->Model);
2636
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 1 AND 10";
2637
		$this->assertEquals($expected, $result);
2638
	}
2639
2640
/**
2641
 * testFieldParsing method
2642
 *
2643
 * @return void
2644
 */
2645
	public function testFieldParsing() {
2646
		$this->Model = new TestModel();
2647
		$result = $this->Dbo->fields($this->Model, 'Vendor', "Vendor.id, COUNT(Model.vendor_id) AS `Vendor`.`count`");
2648
		$expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
2649
		$this->assertEquals($expected, $result);
2650
2651
		$result = $this->Dbo->fields($this->Model, 'Vendor', "`Vendor`.`id`, COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`");
2652
		$expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
2653
		$this->assertEquals($expected, $result);
2654
2655
		$result = $this->Dbo->fields($this->Model, 'Post', "CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name, Node.created");
2656
		$expected = array("CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", "`Node`.`created`");
2657
		$this->assertEquals($expected, $result);
2658
2659
		$result = $this->Dbo->fields($this->Model, null, 'round( (3.55441 * fooField), 3 ) AS test');
2660
		$this->assertEquals(array('round( (3.55441 * fooField), 3 ) AS test'), $result);
2661
2662
		$result = $this->Dbo->fields($this->Model, null, 'ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating');
2663
		$this->assertEquals(array('ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating'), $result);
2664
2665
		$result = $this->Dbo->fields($this->Model, null, 'ROUND(Rating.rate_total / Rating.rate_count,2) AS rating');
2666
		$this->assertEquals(array('ROUND(Rating.rate_total / Rating.rate_count,2) AS rating'), $result);
2667
2668
		$result = $this->Dbo->fields($this->Model, 'Post', "Node.created, CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name");
2669
		$expected = array("`Node`.`created`", "CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name");
2670
		$this->assertEquals($expected, $result);
2671
2672
		$result = $this->Dbo->fields($this->Model, 'Post', "2.2,COUNT(*), SUM(Something.else) as sum, Node.created, CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name,Post.title,Post.1,1.1");
2673
		$expected = array(
2674
			'2.2', 'COUNT(*)', 'SUM(`Something`.`else`) as sum', '`Node`.`created`',
2675
			"CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", '`Post`.`title`', '`Post`.`1`', '1.1'
2676
		);
2677
		$this->assertEquals($expected, $result);
2678
2679
		$result = $this->Dbo->fields($this->Model, null, "(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
2680
		$expected = array("(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
2681
		$this->assertEquals($expected, $result);
2682
2683
		$result = $this->Dbo->fields($this->Model, 'Post');
2684
		$expected = array(
2685
			'`Post`.`id`', '`Post`.`client_id`', '`Post`.`name`', '`Post`.`login`',
2686
			'`Post`.`passwd`', '`Post`.`addr_1`', '`Post`.`addr_2`', '`Post`.`zip_code`',
2687
			'`Post`.`city`', '`Post`.`country`', '`Post`.`phone`', '`Post`.`fax`',
2688
			'`Post`.`url`', '`Post`.`email`', '`Post`.`comments`', '`Post`.`last_login`',
2689
			'`Post`.`created`', '`Post`.`updated`'
2690
		);
2691
		$this->assertEquals($expected, $result);
2692
2693
		$result = $this->Dbo->fields($this->Model, 'Other');
2694
		$expected = array(
2695
			'`Other`.`id`', '`Other`.`client_id`', '`Other`.`name`', '`Other`.`login`',
2696
			'`Other`.`passwd`', '`Other`.`addr_1`', '`Other`.`addr_2`', '`Other`.`zip_code`',
2697
			'`Other`.`city`', '`Other`.`country`', '`Other`.`phone`', '`Other`.`fax`',
2698
			'`Other`.`url`', '`Other`.`email`', '`Other`.`comments`', '`Other`.`last_login`',
2699
			'`Other`.`created`', '`Other`.`updated`'
2700
		);
2701
		$this->assertEquals($expected, $result);
2702
2703
		$result = $this->Dbo->fields($this->Model, null, array(), false);
2704
		$expected = array('id', 'client_id', 'name', 'login', 'passwd', 'addr_1', 'addr_2', 'zip_code', 'city', 'country', 'phone', 'fax', 'url', 'email', 'comments', 'last_login', 'created', 'updated');
2705
		$this->assertEquals($expected, $result);
2706
2707
		$result = $this->Dbo->fields($this->Model, null, 'COUNT(*)');
2708
		$expected = array('COUNT(*)');
2709
		$this->assertEquals($expected, $result);
2710
2711
		$result = $this->Dbo->fields($this->Model, null, 'SUM(Thread.unread_buyer) AS ' . $this->Dbo->name('sum_unread_buyer'));
2712
		$expected = array('SUM(`Thread`.`unread_buyer`) AS `sum_unread_buyer`');
2713
		$this->assertEquals($expected, $result);
2714
2715
		$result = $this->Dbo->fields($this->Model, null, 'name, count(*)');
2716
		$expected = array('`TestModel`.`name`', 'count(*)');
2717
		$this->assertEquals($expected, $result);
2718
2719
		$result = $this->Dbo->fields($this->Model, null, 'count(*), name');
2720
		$expected = array('count(*)', '`TestModel`.`name`');
2721
		$this->assertEquals($expected, $result);
2722
2723
		$result = $this->Dbo->fields(
2724
			$this->Model, null, 'field1, field2, field3, count(*), name'
2725
		);
2726
		$expected = array(
2727
			'`TestModel`.`field1`', '`TestModel`.`field2`',
2728
			'`TestModel`.`field3`', 'count(*)', '`TestModel`.`name`'
2729
		);
2730
		$this->assertEquals($expected, $result);
2731
2732
		$result = $this->Dbo->fields($this->Model, null, array('dayofyear(now())'));
2733
		$expected = array('dayofyear(now())');
2734
		$this->assertEquals($expected, $result);
2735
2736
		$result = $this->Dbo->fields($this->Model, null, array('MAX(Model.field) As Max'));
2737
		$expected = array('MAX(`Model`.`field`) As Max');
2738
		$this->assertEquals($expected, $result);
2739
2740
		$result = $this->Dbo->fields($this->Model, null, array('Model.field AS AnotherName'));
2741
		$expected = array('`Model`.`field` AS `AnotherName`');
2742
		$this->assertEquals($expected, $result);
2743
2744
		$result = $this->Dbo->fields($this->Model, null, array('field AS AnotherName'));
2745
		$expected = array('`field` AS `AnotherName`');
2746
		$this->assertEquals($expected, $result);
2747
2748
		$result = $this->Dbo->fields($this->Model, null, array(
2749
			'TestModel.field AS AnotherName'
2750
		));
2751
		$expected = array('`TestModel`.`field` AS `AnotherName`');
2752
		$this->assertEquals($expected, $result);
2753
2754
		$result = $this->Dbo->fields($this->Model, 'Foo', array(
2755
			'id', 'title', '(user_count + discussion_count + post_count) AS score'
2756
		));
2757
		$expected = array(
2758
			'`Foo`.`id`',
2759
			'`Foo`.`title`',
2760
			'(user_count + discussion_count + post_count) AS score'
2761
		);
2762
		$this->assertEquals($expected, $result);
2763
	}
2764
2765
/**
2766
 * test that fields() will accept objects made from DboSource::expression
2767
 *
2768
 * @return void
2769
 */
2770
	public function testFieldsWithExpression() {
2771
		$this->Model = new TestModel;
2772
		$expression = $this->Dbo->expression("CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col");
2773
		$result = $this->Dbo->fields($this->Model, null, array("id", $expression));
2774
		$expected = array(
2775
			'`TestModel`.`id`',
2776
			"CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col"
2777
		);
2778
		$this->assertEquals($expected, $result);
2779
	}
2780
2781
/**
2782
 * testRenderStatement method
2783
 *
2784
 * @return void
2785
 */
2786
	public function testRenderStatement() {
2787
		$result = $this->Dbo->renderStatement('select', array(
2788
			'fields' => 'id', 'table' => 'table', 'conditions' => 'WHERE 1=1',
2789
			'alias' => '', 'joins' => '', 'order' => '', 'limit' => '', 'group' => ''
2790
		));
2791
		$this->assertRegExp('/^\s*SELECT\s+id\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
2792
2793
		$result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
2794
		$this->assertRegExp('/^\s*UPDATE\s+table\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
2795
2796
		$result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
2797
		$this->assertRegExp('/^\s*UPDATE\s+table\s+AS\s+alias\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
2798
2799
		$result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
2800
		$this->assertRegExp('/^\s*DELETE\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
2801
2802
		$result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
2803
		$this->assertRegExp('/^\s*DELETE\s+alias\s+FROM\s+table\s+AS\s+alias\s+WHERE\s+1=1\s*$/', $result);
2804
	}
2805
2806
/**
2807
 * testSchema method
2808
 *
2809
 * @return void
2810
 */
2811
	public function testSchema() {
2812
		$Schema = new CakeSchema();
2813
		$Schema->tables = array('table' => array(), 'anotherTable' => array());
2814
2815
		$result = $this->Dbo->dropSchema($Schema, 'non_existing');
2816
		$this->assertTrue(empty($result));
2817
2818
		$result = $this->Dbo->dropSchema($Schema, 'table');
2819
		$this->assertRegExp('/^\s*DROP TABLE IF EXISTS\s+' . $this->Dbo->fullTableName('table') . ';\s*$/s', $result);
2820
	}
2821
2822
/**
2823
 * testDropSchemaNoSchema method
2824
 *
2825
 * @expectedException PHPUnit_Framework_Error
2826
 * @return void
2827
 */
2828
	public function testDropSchemaNoSchema() {
2829
		$this->Dbo->dropSchema(null);
2830
	}
2831
2832
/**
2833
 * testOrderParsing method
2834
 *
2835
 * @return void
2836
 */
2837
	public function testOrderParsing() {
2838
		$result = $this->Dbo->order("ADDTIME(Event.time_begin, '-06:00:00') ASC");
2839
		$expected = " ORDER BY ADDTIME(`Event`.`time_begin`, '-06:00:00') ASC";
2840
		$this->assertEquals($expected, $result);
2841
2842
		$result = $this->Dbo->order("title, id");
2843
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2844
2845
		$result = $this->Dbo->order("title desc, id desc");
2846
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
2847
2848
		$result = $this->Dbo->order(array("title desc, id desc"));
2849
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
2850
2851
		$result = $this->Dbo->order(array("title", "id"));
2852
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2853
2854
		$result = $this->Dbo->order(array(array('title'), array('id')));
2855
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2856
2857
		$result = $this->Dbo->order(array("Post.title" => 'asc', "Post.id" => 'desc'));
2858
		$this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
2859
2860
		$result = $this->Dbo->order(array(array("Post.title" => 'asc', "Post.id" => 'desc')));
2861
		$this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
2862
2863
		$result = $this->Dbo->order(array("title"));
2864
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
2865
2866
		$result = $this->Dbo->order(array(array("title")));
2867
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
2868
2869
		$result = $this->Dbo->order("Dealer.id = 7 desc, Dealer.id = 3 desc, Dealer.title asc");
2870
		$expected = " ORDER BY `Dealer`.`id` = 7 desc, `Dealer`.`id` = 3 desc, `Dealer`.`title` asc";
2871
		$this->assertEquals($expected, $result);
2872
2873
		$result = $this->Dbo->order(array("Page.name" => "='test' DESC"));
2874
		$this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*='test'\s+DESC\s*$/", $result);
2875
2876
		$result = $this->Dbo->order("Page.name = 'view' DESC");
2877
		$this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*=\s*'view'\s+DESC\s*$/", $result);
2878
2879
		$result = $this->Dbo->order("(Post.views)");
2880
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\s+ASC\s*$/", $result);
2881
2882
		$result = $this->Dbo->order("(Post.views)*Post.views");
2883
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\*`Post`\.`views`\s+ASC\s*$/", $result);
2884
2885
		$result = $this->Dbo->order("(Post.views) * Post.views");
2886
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\) \* `Post`\.`views`\s+ASC\s*$/", $result);
2887
2888
		$result = $this->Dbo->order("(Model.field1 + Model.field2) * Model.field3");
2889
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field1` \+ `Model`\.`field2`\) \* `Model`\.`field3`\s+ASC\s*$/", $result);
2890
2891
		$result = $this->Dbo->order("Model.name+0 ASC");
2892
		$this->assertRegExp("/^\s*ORDER BY\s+`Model`\.`name`\+0\s+ASC\s*$/", $result);
2893
2894
		$result = $this->Dbo->order("Anuncio.destaque & 2 DESC");
2895
		$expected = ' ORDER BY `Anuncio`.`destaque` & 2 DESC';
2896
		$this->assertEquals($expected, $result);
2897
2898
		$result = $this->Dbo->order("3963.191 * id");
2899
		$expected = ' ORDER BY 3963.191 * id ASC';
2900
		$this->assertEquals($expected, $result);
2901
2902
		$result = $this->Dbo->order(array('Property.sale_price IS NULL'));
2903
		$expected = ' ORDER BY `Property`.`sale_price` IS NULL ASC';
2904
		$this->assertEquals($expected, $result);
2905
	}
2906
2907
/**
2908
 * testComplexSortExpression method
2909
 *
2910
 * @return void
2911
 */
2912
	public function testComplexSortExpression() {
2913
		$result = $this->Dbo->order(array('(Model.field > 100) DESC', 'Model.field ASC'));
2914
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field`\s+>\s+100\)\s+DESC,\s+`Model`\.`field`\s+ASC\s*$/", $result);
2915
	}
2916
2917
/**
2918
 * testCalculations method
2919
 *
2920
 * @return void
2921
 */
2922
	public function testCalculations() {
2923
		$this->Model = new TestModel();
2924
		$result = $this->Dbo->calculate($this->Model, 'count');
2925
		$this->assertEquals('COUNT(*) AS `count`', $result);
2926
2927
		$result = $this->Dbo->calculate($this->Model, 'count', array('id'));
2928
		$this->assertEquals('COUNT(`id`) AS `count`', $result);
2929
2930
		$result = $this->Dbo->calculate(
2931
			$this->Model,
2932
			'count',
2933
			array($this->Dbo->expression('DISTINCT id'))
2934
		);
2935
		$this->assertEquals('COUNT(DISTINCT id) AS `count`', $result);
2936
2937
		$result = $this->Dbo->calculate($this->Model, 'count', array('id', 'id_count'));
2938
		$this->assertEquals('COUNT(`id`) AS `id_count`', $result);
2939
2940
		$result = $this->Dbo->calculate($this->Model, 'count', array('Model.id', 'id_count'));
2941
		$this->assertEquals('COUNT(`Model`.`id`) AS `id_count`', $result);
2942
2943
		$result = $this->Dbo->calculate($this->Model, 'max', array('id'));
2944
		$this->assertEquals('MAX(`id`) AS `id`', $result);
2945
2946
		$result = $this->Dbo->calculate($this->Model, 'max', array('Model.id', 'id'));
2947
		$this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
2948
2949
		$result = $this->Dbo->calculate($this->Model, 'max', array('`Model`.`id`', 'id'));
2950
		$this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
2951
2952
		$result = $this->Dbo->calculate($this->Model, 'min', array('`Model`.`id`', 'id'));
2953
		$this->assertEquals('MIN(`Model`.`id`) AS `id`', $result);
2954
2955
		$result = $this->Dbo->calculate($this->Model, 'min', 'left');
2956
		$this->assertEquals('MIN(`left`) AS `left`', $result);
2957
	}
2958
2959
/**
2960
 * testLength method
2961
 *
2962
 * @return void
2963
 */
2964
	public function testLength() {
2965
		$result = $this->Dbo->length('varchar(255)');
2966
		$expected = 255;
2967
		$this->assertSame($expected, $result);
2968
2969
		$result = $this->Dbo->length('int(11)');
2970
		$expected = 11;
2971
		$this->assertSame($expected, $result);
2972
2973
		$result = $this->Dbo->length('float(5,3)');
2974
		$expected = '5,3';
2975
		$this->assertSame($expected, $result);
2976
2977
		$result = $this->Dbo->length('decimal(5,2)');
2978
		$expected = '5,2';
2979
		$this->assertSame($expected, $result);
2980
2981
		$result = $this->Dbo->length("enum('test','me','now')");
2982
		$expected = 4;
2983
		$this->assertSame($expected, $result);
2984
2985
		$result = $this->Dbo->length("set('a','b','cd')");
2986
		$expected = 2;
2987
		$this->assertSame($expected, $result);
2988
2989
		$result = $this->Dbo->length(false);
2990
		$this->assertTrue($result === null);
2991
2992
		$result = $this->Dbo->length('datetime');
2993
		$expected = null;
2994
		$this->assertSame($expected, $result);
2995
2996
		$result = $this->Dbo->length('text');
2997
		$expected = null;
2998
		$this->assertSame($expected, $result);
2999
	}
3000
3001
/**
3002
 * testBuildIndex method
3003
 *
3004
 * @return void
3005
 */
3006
	public function testBuildIndex() {
3007
		$data = array(
3008
			'PRIMARY' => array('column' => 'id')
3009
		);
3010
		$result = $this->Dbo->buildIndex($data);
3011
		$expected = array('PRIMARY KEY  (`id`)');
3012
		$this->assertSame($expected, $result);
3013
3014
		$data = array(
3015
			'MyIndex' => array('column' => 'id', 'unique' => true)
3016
		);
3017
		$result = $this->Dbo->buildIndex($data);
3018
		$expected = array('UNIQUE KEY `MyIndex` (`id`)');
3019
		$this->assertEquals($expected, $result);
3020
3021
		$data = array(
3022
			'MyIndex' => array('column' => array('id', 'name'), 'unique' => true)
3023
		);
3024
		$result = $this->Dbo->buildIndex($data);
3025
		$expected = array('UNIQUE KEY `MyIndex` (`id`, `name`)');
3026
		$this->assertEquals($expected, $result);
3027
3028
		$data = array(
3029
			'MyFtIndex' => array('column' => array('name', 'description'), 'type' => 'fulltext')
3030
		);
3031
		$result = $this->Dbo->buildIndex($data);
3032
		$expected = array('FULLTEXT KEY `MyFtIndex` (`name`, `description`)');
3033
		$this->assertEquals($expected, $result);
3034
3035
		$data = array(
3036
			'MyTextIndex' => array('column' => 'text_field', 'length' => array('text_field' => 20))
3037
		);
3038
		$result = $this->Dbo->buildIndex($data);
3039
		$expected = array('KEY `MyTextIndex` (`text_field`(20))');
3040
		$this->assertEquals($expected, $result);
3041
3042
		$data = array(
3043
			'MyMultiTextIndex' => array('column' => array('text_field1', 'text_field2'), 'length' => array('text_field1' => 20, 'text_field2' => 20))
3044
		);
3045
		$result = $this->Dbo->buildIndex($data);
3046
		$expected = array('KEY `MyMultiTextIndex` (`text_field1`(20), `text_field2`(20))');
3047
		$this->assertEquals($expected, $result);
3048
	}
3049
3050
/**
3051
 * testBuildColumn method
3052
 *
3053
 * @return void
3054
 */
3055
	public function testBuildColumn2() {
3056
		$data = array(
3057
			'name' => 'testName',
3058
			'type' => 'string',
3059
			'length' => 255,
3060
			'default',
3061
			'null' => true,
3062
			'key'
3063
		);
3064
		$result = $this->Dbo->buildColumn($data);
3065
		$expected = '`testName` varchar(255) DEFAULT NULL';
3066
		$this->assertEquals($expected, $result);
3067
3068
		$data = array(
3069
			'name' => 'int_field',
3070
			'type' => 'integer',
3071
			'default' => '',
3072
			'null' => false,
3073
		);
3074
		$restore = $this->Dbo->columns;
3075
3076
		$this->Dbo->columns = array('integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), );
3077
		$result = $this->Dbo->buildColumn($data);
3078
		$expected = '`int_field` int(11) NOT NULL';
3079
		$this->assertEquals($expected, $result);
3080
3081
		$this->Dbo->fieldParameters['param'] = array(
3082
			'value' => 'COLLATE',
3083
			'quote' => false,
3084
			'join' => ' ',
3085
			'column' => 'Collate',
3086
			'position' => 'beforeDefault',
3087
			'options' => array('GOOD', 'OK')
3088
		);
3089
		$data = array(
3090
			'name' => 'int_field',
3091
			'type' => 'integer',
3092
			'default' => '',
3093
			'null' => false,
3094
			'param' => 'BAD'
3095
		);
3096
		$result = $this->Dbo->buildColumn($data);
3097
		$expected = '`int_field` int(11) NOT NULL';
3098
		$this->assertEquals($expected, $result);
3099
3100
		$data = array(
3101
			'name' => 'int_field',
3102
			'type' => 'integer',
3103
			'default' => '',
3104
			'null' => false,
3105
			'param' => 'GOOD'
3106
		);
3107
		$result = $this->Dbo->buildColumn($data);
3108
		$expected = '`int_field` int(11) COLLATE GOOD NOT NULL';
3109
		$this->assertEquals($expected, $result);
3110
3111
		$this->Dbo->columns = $restore;
3112
3113
		$data = array(
3114
			'name' => 'created',
3115
			'type' => 'timestamp',
3116
			'default' => 'current_timestamp',
3117
			'null' => false,
3118
		);
3119
		$result = $this->Dbo->buildColumn($data);
3120
		$expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL';
3121
		$this->assertEquals($expected, $result);
3122
3123
		$data = array(
3124
			'name' => 'created',
3125
			'type' => 'timestamp',
3126
			'default' => 'CURRENT_TIMESTAMP',
3127
			'null' => true,
3128
		);
3129
		$result = $this->Dbo->buildColumn($data);
3130
		$expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP';
3131
		$this->assertEquals($expected, $result);
3132
3133
		$data = array(
3134
			'name' => 'modified',
3135
			'type' => 'timestamp',
3136
			'null' => true,
3137
		);
3138
		$result = $this->Dbo->buildColumn($data);
3139
		$expected = '`modified` timestamp NULL';
3140
		$this->assertEquals($expected, $result);
3141
3142
		$data = array(
3143
			'name' => 'modified',
3144
			'type' => 'timestamp',
3145
			'default' => null,
3146
			'null' => true,
3147
		);
3148
		$result = $this->Dbo->buildColumn($data);
3149
		$expected = '`modified` timestamp NULL';
3150
		$this->assertEquals($expected, $result);
3151
	}
3152
3153
/**
3154
 * testBuildColumnBadType method
3155
 *
3156
 * @expectedException PHPUnit_Framework_Error
3157
 * @return void
3158
 */
3159
	public function testBuildColumnBadType() {
3160
		$data = array(
3161
			'name' => 'testName',
3162
			'type' => 'varchar(255)',
3163
			'default',
3164
			'null' => true,
3165
			'key'
3166
		);
3167
		$this->Dbo->buildColumn($data);
3168
	}
3169
3170
/**
3171
 * test hasAny()
3172
 *
3173
 * @return void
3174
 */
3175
	public function testHasAny() {
3176
		$db = $this->Dbo->config['database'];
3177
		$this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute', 'value'));
3178
		$this->Dbo->config['database'] = $db;
3179
3180
		$this->Model = $this->getMock('TestModel', array('getDataSource'));
3181
		$this->Model->expects($this->any())
3182
			->method('getDataSource')
3183
			->will($this->returnValue($this->Dbo));
3184
3185
		$this->Dbo->expects($this->at(0))->method('value')
3186
			->with('harry')
3187
			->will($this->returnValue("'harry'"));
3188
3189
		$modelTable = $this->Dbo->fullTableName($this->Model);
3190
		$this->Dbo->expects($this->at(1))->method('execute')
3191
			->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE `TestModel`.`name` = \'harry\'');
3192
		$this->Dbo->expects($this->at(2))->method('execute')
3193
			->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE 1 = 1');
3194
3195
		$this->Dbo->hasAny($this->Model, array('TestModel.name' => 'harry'));
3196
		$this->Dbo->hasAny($this->Model, array());
3197
	}
3198
3199
/**
3200
 * test fields generating usable virtual fields to use in query
3201
 *
3202
 * @return void
3203
 */
3204
	public function testVirtualFields() {
3205
		$this->loadFixtures('Article', 'Comment', 'Tag');
3206
		$this->Dbo->virtualFieldSeparator = '__';
3207
		$Article = ClassRegistry::init('Article');
3208
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3209
		$Article->virtualFields = array(
3210
			'this_moment' => 'NOW()',
3211
			'two' => '1 + 1',
3212
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3213
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3214
		);
3215
		$result = $this->Dbo->fields($Article);
3216
		$expected = array(
3217
			'`Article`.`id`',
3218
			'`Article`.`user_id`',
3219
			'`Article`.`title`',
3220
			'`Article`.`body`',
3221
			'`Article`.`published`',
3222
			'`Article`.`created`',
3223
			'`Article`.`updated`',
3224
			'(NOW()) AS  `Article__this_moment`',
3225
			'(1 + 1) AS  `Article__two`',
3226
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3227
		);
3228
3229
		$this->assertEquals($expected, $result);
3230
3231
		$result = $this->Dbo->fields($Article, null, array('this_moment', 'title'));
3232
		$expected = array(
3233
			'`Article`.`title`',
3234
			'(NOW()) AS  `Article__this_moment`',
3235
		);
3236
		$this->assertEquals($expected, $result);
3237
3238
		$result = $this->Dbo->fields($Article, null, array('Article.title', 'Article.this_moment'));
3239
		$expected = array(
3240
			'`Article`.`title`',
3241
			'(NOW()) AS  `Article__this_moment`',
3242
		);
3243
		$this->assertEquals($expected, $result);
3244
3245
		$result = $this->Dbo->fields($Article, null, array('Article.this_moment', 'Article.title'));
3246
		$expected = array(
3247
			'`Article`.`title`',
3248
			'(NOW()) AS  `Article__this_moment`',
3249
		);
3250
		$this->assertEquals($expected, $result);
3251
3252
		$result = $this->Dbo->fields($Article, null, array('Article.*'));
3253
		$expected = array(
3254
			'`Article`.*',
3255
			'(NOW()) AS  `Article__this_moment`',
3256
			'(1 + 1) AS  `Article__two`',
3257
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3258
		);
3259
		$this->assertEquals($expected, $result);
3260
3261
		$result = $this->Dbo->fields($Article, null, array('*'));
3262
		$expected = array(
3263
			'*',
3264
			'(NOW()) AS  `Article__this_moment`',
3265
			'(1 + 1) AS  `Article__two`',
3266
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3267
		);
3268
		$this->assertEquals($expected, $result);
3269
	}
3270
3271
/**
3272
 * test conditions to generate query conditions for virtual fields
3273
 *
3274
 * @return void
3275
 */
3276
	public function testVirtualFieldsInConditions() {
3277
		$Article = ClassRegistry::init('Article');
3278
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3279
3280
		$Article->virtualFields = array(
3281
			'this_moment' => 'NOW()',
3282
			'two' => '1 + 1',
3283
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3284
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3285
		);
3286
		$conditions = array('two' => 2);
3287
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3288
		$expected = '(1 + 1) = 2';
3289
		$this->assertEquals($expected, $result);
3290
3291
		$conditions = array('this_moment BETWEEN ? AND ?' => array(1, 2));
3292
		$expected = 'NOW() BETWEEN 1 AND 2';
3293
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3294
		$this->assertEquals($expected, $result);
3295
3296
		$conditions = array('comment_count >' => 5);
3297
		$expected = "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) > 5";
3298
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3299
		$this->assertEquals($expected, $result);
3300
3301
		$conditions = array('NOT' => array('two' => 2));
3302
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3303
		$expected = 'NOT ((1 + 1) = 2)';
3304
		$this->assertEquals($expected, $result);
3305
	}
3306
3307
/**
3308
 * test that virtualFields with complex functions and aliases work.
3309
 *
3310
 * @return void
3311
 */
3312
	public function testConditionsWithComplexVirtualFields() {
3313
		$Article = ClassRegistry::init('Article', 'Comment', 'Tag');
3314
		$Article->virtualFields = array(
3315
			'distance' => 'ACOS(SIN(20 * PI() / 180)
3316
					* SIN(Article.latitude * PI() / 180)
3317
					+ COS(20 * PI() / 180)
3318
					* COS(Article.latitude * PI() / 180)
3319
					* COS((50 - Article.longitude) * PI() / 180)
3320
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3321
		);
3322
		$conditions = array('distance >=' => 20);
3323
		$result = $this->Dbo->conditions($conditions, true, true, $Article);
3324
3325
		$this->assertRegExp('/\) >= 20/', $result);
3326
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result);
3327
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result);
3328
	}
3329
3330
/**
3331
 * test calculate to generate claculate statements on virtual fields
3332
 *
3333
 * @return void
3334
 */
3335
	public function testVirtualFieldsInCalculate() {
3336
		$Article = ClassRegistry::init('Article');
3337
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3338
		$Article->virtualFields = array(
3339
			'this_moment' => 'NOW()',
3340
			'two' => '1 + 1',
3341
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3342
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3343
		);
3344
3345
		$result = $this->Dbo->calculate($Article, 'count', array('this_moment'));
3346
		$expected = 'COUNT(NOW()) AS `count`';
3347
		$this->assertEquals($expected, $result);
3348
3349
		$result = $this->Dbo->calculate($Article, 'max', array('comment_count'));
3350
		$expected = "MAX(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `comment_count`";
3351
		$this->assertEquals($expected, $result);
3352
	}
3353
3354
/**
3355
 * test reading virtual fields containing newlines when recursive > 0
3356
 *
3357
 * @return void
3358
 */
3359
	public function testReadVirtualFieldsWithNewLines() {
3360
		$Article = new Article();
3361
		$Article->recursive = 1;
3362
		$Article->virtualFields = array(
3363
			'test' => '
3364
			User.id + User.id
3365
			'
3366
		);
3367
		$result = $this->Dbo->fields($Article, null, array());
3368
		$result = $this->Dbo->fields($Article, $Article->alias, $result);
3369
		$this->assertRegExp('/[`\"]User[`\"]\.[`\"]id[`\"] \+ [`\"]User[`\"]\.[`\"]id[`\"]/', $result[7]);
3370
	}
3371
3372
/**
3373
 * test group to generate GROUP BY statements on virtual fields
3374
 *
3375
 * @return void
3376
 */
3377
	public function testVirtualFieldsInGroup() {
3378
		$Article = ClassRegistry::init('Article');
3379
		$Article->virtualFields = array(
3380
			'this_year' => 'YEAR(Article.created)'
3381
		);
3382
3383
		$result = $this->Dbo->group('this_year', $Article);
3384
3385
		$expected = " GROUP BY (YEAR(`Article`.`created`))";
3386
		$this->assertEquals($expected, $result);
3387
	}
3388
3389
/**
3390
 * test that virtualFields with complex functions and aliases work.
3391
 *
3392
 * @return void
3393
 */
3394
	public function testFieldsWithComplexVirtualFields() {
3395
		$Article = new Article();
3396
		$Article->virtualFields = array(
3397
			'distance' => 'ACOS(SIN(20 * PI() / 180)
3398
					* SIN(Article.latitude * PI() / 180)
3399
					+ COS(20 * PI() / 180)
3400
					* COS(Article.latitude * PI() / 180)
3401
					* COS((50 - Article.longitude) * PI() / 180)
3402
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3403
		);
3404
3405
		$fields = array('id', 'distance');
3406
		$result = $this->Dbo->fields($Article, null, $fields);
3407
		$qs = $this->Dbo->startQuote;
3408
		$qe = $this->Dbo->endQuote;
3409
3410
		$this->assertEquals("{$qs}Article{$qe}.{$qs}id{$qe}", $result[0]);
3411
		$this->assertRegExp('/Article__distance/', $result[1]);
3412
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result[1]);
3413
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result[1]);
3414
	}
3415
3416
/**
3417
 * test that execute runs queries.
3418
 *
3419
 * @return void
3420
 */
3421
	public function testExecute() {
3422
		$query = 'SELECT * FROM ' . $this->Dbo->fullTableName('articles') . ' WHERE 1 = 1';
3423
		$this->Dbo->took = null;
3424
		$this->Dbo->affected = null;
3425
		$result = $this->Dbo->execute($query, array('log' => false));
3426
		$this->assertNotNull($result, 'No query performed! %s');
3427
		$this->assertNull($this->Dbo->took, 'Stats were set %s');
3428
		$this->assertNull($this->Dbo->affected, 'Stats were set %s');
3429
3430
		$result = $this->Dbo->execute($query);
3431
		$this->assertNotNull($result, 'No query performed! %s');
3432
		$this->assertNotNull($this->Dbo->took, 'Stats were not set %s');
3433
		$this->assertNotNull($this->Dbo->affected, 'Stats were not set %s');
3434
	}
3435
3436
/**
3437
 * test a full example of using virtual fields
3438
 *
3439
 * @return void
3440
 */
3441
	public function testVirtualFieldsFetch() {
3442
		$this->loadFixtures('Article', 'Comment');
3443
3444
		$Article = ClassRegistry::init('Article');
3445
		$Article->virtualFields = array(
3446
			'comment_count' => 'SELECT COUNT(*) FROM ' . $this->Dbo->fullTableName('comments') .
3447
				' WHERE Article.id = ' . $this->Dbo->fullTableName('comments') . '.article_id'
3448
		);
3449
3450
		$conditions = array('comment_count >' => 2);
3451
		$query = 'SELECT ' . implode(',', $this->Dbo->fields($Article, null, array('id', 'comment_count'))) .
3452
				' FROM ' . $this->Dbo->fullTableName($Article) . ' Article ' . $this->Dbo->conditions($conditions, true, true, $Article);
3453
		$result = $this->Dbo->fetchAll($query);
3454
		$expected = array(array(
3455
			'Article' => array('id' => 1, 'comment_count' => 4)
3456
		));
3457
		$this->assertEquals($expected, $result);
3458
	}
3459
3460
/**
3461
 * test reading complex virtualFields with subqueries.
3462
 *
3463
 * @return void
3464
 */
3465
	public function testVirtualFieldsComplexRead() {
3466
		$this->loadFixtures('DataTest', 'Article', 'Comment', 'User', 'Tag', 'ArticlesTag');
3467
3468
		$Article = ClassRegistry::init('Article');
3469
		$commentTable = $this->Dbo->fullTableName('comments');
3470
		$Article = ClassRegistry::init('Article');
3471
		$Article->virtualFields = array(
3472
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentTable .
3473
				' AS Comment WHERE Article.id = Comment.article_id'
3474
		);
3475
		$result = $Article->find('all');
3476
		$this->assertTrue(count($result) > 0);
3477
		$this->assertTrue($result[0]['Article']['comment_count'] > 0);
3478
3479
		$DataTest = ClassRegistry::init('DataTest');
3480
		$DataTest->virtualFields = array(
3481
			'complicated' => 'ACOS(SIN(20 * PI() / 180)
3482
				* SIN(DataTest.float * PI() / 180)
3483
				+ COS(20 * PI() / 180)
3484
				* COS(DataTest.count * PI() / 180)
3485
				* COS((50 - DataTest.float) * PI() / 180)
3486
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3487
		);
3488
		$result = $DataTest->find('all');
3489
		$this->assertTrue(count($result) > 0);
3490
		$this->assertTrue($result[0]['DataTest']['complicated'] > 0);
3491
	}
3492
3493
/**
3494
 * testIntrospectType method
3495
 *
3496
 * @return void
3497
 */
3498
	public function testIntrospectType() {
3499
		$this->assertEquals('integer', $this->Dbo->introspectType(0));
3500
		$this->assertEquals('integer', $this->Dbo->introspectType(2));
3501
		$this->assertEquals('string', $this->Dbo->introspectType('2'));
3502
		$this->assertEquals('string', $this->Dbo->introspectType('2.2'));
3503
		$this->assertEquals('float', $this->Dbo->introspectType(2.2));
3504
		$this->assertEquals('string', $this->Dbo->introspectType('stringme'));
3505
		$this->assertEquals('string', $this->Dbo->introspectType('0stringme'));
3506
3507
		$data = array(2.2);
3508
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3509
3510
		$data = array('2.2');
3511
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3512
3513
		$data = array(2);
3514
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3515
3516
		$data = array('2');
3517
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3518
3519
		$data = array('string');
3520
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3521
3522
		$data = array(2.2, '2.2');
3523
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3524
3525
		$data = array(2, '2');
3526
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3527
3528
		$data = array('string one', 'string two');
3529
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3530
3531
		$data = array('2.2', 3);
3532
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3533
3534
		$data = array('2.2', '0stringme');
3535
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3536
3537
		$data = array(2.2, 3);
3538
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3539
3540
		$data = array(2.2, '0stringme');
3541
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3542
3543
		$data = array(2, 'stringme');
3544
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3545
3546
		$data = array(2, '2.2', 'stringgme');
3547
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3548
3549
		$data = array(2, '2.2');
3550
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3551
3552
		$data = array(2, 2.2);
3553
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3554
3555
		// null
3556
		$result = $this->Dbo->value(null, 'boolean');
3557
		$this->assertEquals('NULL', $result);
3558
3559
		// EMPTY STRING
3560
		$result = $this->Dbo->value('', 'boolean');
3561
		$this->assertEquals("'0'", $result);
3562
3563
		// BOOLEAN
3564
		$result = $this->Dbo->value('true', 'boolean');
3565
		$this->assertEquals("'1'", $result);
3566
3567
		$result = $this->Dbo->value('false', 'boolean');
3568
		$this->assertEquals("'1'", $result);
3569
3570
		$result = $this->Dbo->value(true, 'boolean');
3571
		$this->assertEquals("'1'", $result);
3572
3573
		$result = $this->Dbo->value(false, 'boolean');
3574
		$this->assertEquals("'0'", $result);
3575
3576
		$result = $this->Dbo->value(1, 'boolean');
3577
		$this->assertEquals("'1'", $result);
3578
3579
		$result = $this->Dbo->value(0, 'boolean');
3580
		$this->assertEquals("'0'", $result);
3581
3582
		$result = $this->Dbo->value('abc', 'boolean');
3583
		$this->assertEquals("'1'", $result);
3584
3585
		$result = $this->Dbo->value(1.234, 'boolean');
3586
		$this->assertEquals("'1'", $result);
3587
3588
		$result = $this->Dbo->value('1.234e05', 'boolean');
3589
		$this->assertEquals("'1'", $result);
3590
3591
		// NUMBERS
3592
		$result = $this->Dbo->value(123, 'integer');
3593
		$this->assertEquals(123, $result);
3594
3595
		$result = $this->Dbo->value('123', 'integer');
3596
		$this->assertEquals('123', $result);
3597
3598
		$result = $this->Dbo->value('0123', 'integer');
3599
		$this->assertEquals("'0123'", $result);
3600
3601
		$result = $this->Dbo->value('0x123ABC', 'integer');
3602
		$this->assertEquals("'0x123ABC'", $result);
3603
3604
		$result = $this->Dbo->value('0x123', 'integer');
3605
		$this->assertEquals("'0x123'", $result);
3606
3607
		$result = $this->Dbo->value(1.234, 'float');
3608
		$this->assertEquals(1.234, $result);
3609
3610
		$result = $this->Dbo->value('1.234', 'float');
3611
		$this->assertEquals('1.234', $result);
3612
3613
		$result = $this->Dbo->value(' 1.234 ', 'float');
3614
		$this->assertEquals("' 1.234 '", $result);
3615
3616
		$result = $this->Dbo->value('1.234e05', 'float');
3617
		$this->assertEquals("'1.234e05'", $result);
3618
3619
		$result = $this->Dbo->value('1.234e+5', 'float');
3620
		$this->assertEquals("'1.234e+5'", $result);
3621
3622
		$result = $this->Dbo->value('1,234', 'float');
3623
		$this->assertEquals("'1,234'", $result);
3624
3625
		$result = $this->Dbo->value('FFF', 'integer');
3626
		$this->assertEquals("'FFF'", $result);
3627
3628
		$result = $this->Dbo->value('abc', 'integer');
3629
		$this->assertEquals("'abc'", $result);
3630
3631
		// STRINGS
3632
		$result = $this->Dbo->value('123', 'string');
3633
		$this->assertEquals("'123'", $result);
3634
3635
		$result = $this->Dbo->value(123, 'string');
3636
		$this->assertEquals("'123'", $result);
3637
3638
		$result = $this->Dbo->value(1.234, 'string');
3639
		$this->assertEquals("'1.234'", $result);
3640
3641
		$result = $this->Dbo->value('abc', 'string');
3642
		$this->assertEquals("'abc'", $result);
3643
3644
		$result = $this->Dbo->value(' abc ', 'string');
3645
		$this->assertEquals("' abc '", $result);
3646
3647
		$result = $this->Dbo->value('a bc', 'string');
3648
		$this->assertEquals("'a bc'", $result);
3649
	}
3650
3651
/**
3652
 * testRealQueries method
3653
 *
3654
 * @return void
3655
 */
3656
	public function testRealQueries() {
3657
		$this->loadFixtures('Apple', 'Article', 'User', 'Comment', 'Tag', 'Sample', 'ArticlesTag');
3658
3659
		$Apple = ClassRegistry::init('Apple');
3660
		$Article = ClassRegistry::init('Article');
3661
3662
		$result = $this->Dbo->rawQuery('SELECT color, name FROM ' . $this->Dbo->fullTableName('apples'));
3663
		$this->assertTrue(!empty($result));
3664
3665
		$result = $this->Dbo->fetchRow($result);
3666
		$expected = array($this->Dbo->fullTableName('apples', false, false) => array(
3667
			'color' => 'Red 1',
3668
			'name' => 'Red Apple 1'
3669
		));
3670
		$this->assertEquals($expected, $result);
3671
3672
		$result = $this->Dbo->fetchAll('SELECT name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
3673
		$expected = array(
3674
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Red Apple 1')),
3675
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Bright Red Apple')),
3676
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'green blue')),
3677
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Test Name')),
3678
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Blue Green')),
3679
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'My new apple')),
3680
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Some odd color'))
3681
		);
3682
		$this->assertEquals($expected, $result);
3683
3684
		$result = $this->Dbo->field($this->Dbo->fullTableName('apples', false, false), 'SELECT color, name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
3685
		$expected = array(
3686
			'color' => 'Red 1',
3687
			'name' => 'Red Apple 1'
3688
		);
3689
		$this->assertEquals($expected, $result);
3690
3691
		$Apple->unbindModel(array(), false);
3692
		$result = $this->Dbo->read($Apple, array(
3693
			'fields' => array($Apple->escapeField('name')),
3694
			'conditions' => null,
3695
			'recursive' => -1
3696
		));
3697
		$expected = array(
3698
			array('Apple' => array('name' => 'Red Apple 1')),
3699
			array('Apple' => array('name' => 'Bright Red Apple')),
3700
			array('Apple' => array('name' => 'green blue')),
3701
			array('Apple' => array('name' => 'Test Name')),
3702
			array('Apple' => array('name' => 'Blue Green')),
3703
			array('Apple' => array('name' => 'My new apple')),
3704
			array('Apple' => array('name' => 'Some odd color'))
3705
		);
3706
		$this->assertEquals($expected, $result);
3707
3708
		$result = $this->Dbo->read($Article, array(
3709
			'fields' => array('id', 'user_id', 'title'),
3710
			'conditions' => null,
3711
			'recursive' => 1
3712
		));
3713
3714
		$this->assertTrue(Set::matches('/Article[id=1]', $result));
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->Dbo->read($Articl...ull, 'recursive' => 1)) on line 3708 can also be of type boolean; however, Set::matches() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3715
		$this->assertTrue(Set::matches('/Comment[id=1]', $result));
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->Dbo->read($Articl...ull, 'recursive' => 1)) on line 3708 can also be of type boolean; however, Set::matches() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3716
		$this->assertTrue(Set::matches('/Comment[id=2]', $result));
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->Dbo->read($Articl...ull, 'recursive' => 1)) on line 3708 can also be of type boolean; however, Set::matches() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3717
		$this->assertFalse(Set::matches('/Comment[id=10]', $result));
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->Dbo->read($Articl...ull, 'recursive' => 1)) on line 3708 can also be of type boolean; however, Set::matches() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3718
	}
3719
3720
/**
3721
 * @expectedException MissingConnectionException
3722
 * @return void
3723
 */
3724
	public function testExceptionOnBrokenConnection() {
3725
		new Mysql(array(
3726
			'driver' => 'mysql',
3727
			'host' => 'imaginary_host',
3728
			'login' => 'mark',
3729
			'password' => 'inyurdatabase',
3730
			'database' => 'imaginary'
3731
		));
3732
	}
3733
3734
/**
3735
 * testStatements method
3736
 *
3737
 * @return void
3738
 */
3739
	public function testUpdateStatements() {
3740
		$this->loadFixtures('Article', 'User');
3741
		$test = ConnectionManager::getDatasource('test');
3742
		$db = $test->config['database'];
3743
3744
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
3745
3746
		$this->Dbo->expects($this->at(0))->method('execute')
3747
			->with("UPDATE `$db`.`articles` SET `field1` = 'value1'  WHERE 1 = 1");
3748
3749
		$this->Dbo->expects($this->at(1))->method('execute')
3750
			->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
3751
				"(`Article`.`user_id` = `User`.`id`)" .
3752
				" SET `Article`.`field1` = 2  WHERE 2=2");
3753
3754
		$this->Dbo->expects($this->at(2))->method('execute')
3755
			->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
3756
				"(`Article`.`user_id` = `User`.`id`)" .
3757
				" SET `Article`.`field1` = 'value'  WHERE `index` = 'val'");
3758
3759
		$Article = new Article();
3760
3761
		$this->Dbo->update($Article, array('field1'), array('value1'));
3762
		$this->Dbo->update($Article, array('field1'), array('2'), '2=2');
3763
		$this->Dbo->update($Article, array('field1'), array("'value'"), array('index' => 'val'));
3764
	}
3765
3766
/**
3767
 * Test deletes with a mock.
3768
 *
3769
 * @return void
3770
 */
3771
	public function testDeleteStatements() {
3772
		$this->loadFixtures('Article', 'User');
3773
		$test = ConnectionManager::getDatasource('test');
3774
		$db = $test->config['database'];
3775
3776
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
3777
3778
		$this->Dbo->expects($this->at(0))->method('execute')
3779
			->with("DELETE  FROM `$db`.`articles`  WHERE 1 = 1");
3780
3781
		$this->Dbo->expects($this->at(1))->method('execute')
3782
			->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
3783
				"ON (`Article`.`user_id` = `User`.`id`)" .
3784
				"  WHERE 1 = 1");
3785
3786
		$this->Dbo->expects($this->at(2))->method('execute')
3787
			->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
3788
				"ON (`Article`.`user_id` = `User`.`id`)" .
3789
				"  WHERE 2=2");
3790
		$Article = new Article();
3791
3792
		$this->Dbo->delete($Article);
3793
		$this->Dbo->delete($Article, true);
3794
		$this->Dbo->delete($Article, '2=2');
3795
	}
3796
3797
/**
3798
 * Test truncate with a mock.
3799
 *
3800
 * @return void
3801
 */
3802 View Code Duplication
	public function testTruncateStatements() {
3803
		$this->loadFixtures('Article', 'User');
3804
		$db = ConnectionManager::getDatasource('test');
3805
		$schema = $db->config['database'];
3806
		$Article = new Article();
3807
3808
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($db->config));
3809
3810
		$this->Dbo->expects($this->at(0))->method('execute')
3811
			->with("TRUNCATE TABLE `$schema`.`articles`");
3812
		$this->Dbo->truncate($Article);
3813
3814
		$this->Dbo->expects($this->at(0))->method('execute')
3815
			->with("TRUNCATE TABLE `$schema`.`articles`");
3816
		$this->Dbo->truncate('articles');
3817
3818
		// #2355: prevent duplicate prefix
3819
		$this->Dbo->config['prefix'] = 'tbl_';
3820
		$Article->tablePrefix = 'tbl_';
3821
		$this->Dbo->expects($this->at(0))->method('execute')
3822
			->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
3823
		$this->Dbo->truncate($Article);
3824
3825
		$this->Dbo->expects($this->at(0))->method('execute')
3826
			->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
3827
		$this->Dbo->truncate('articles');
3828
	}
3829
3830
/**
3831
 * Test nested transaction
3832
 *
3833
 * @return void
3834
 */
3835
	public function testNestedTransaction() {
3836
		$nested = $this->Dbo->useNestedTransactions;
3837
		$this->Dbo->useNestedTransactions = true;
3838
		if ($this->Dbo->nestedTransactionSupported() === false) {
3839
			$this->Dbo->useNestedTransactions = $nested;
3840
			$this->skipIf(true, 'The MySQL server do not support nested transaction');
3841
		}
3842
3843
		$this->loadFixtures('Inno');
3844
		$model = ClassRegistry::init('Inno');
3845
		$model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
3846
		$model->cacheQueries = false;
3847
		$this->Dbo->cacheMethods = false;
3848
3849
		$this->assertTrue($this->Dbo->begin());
3850
		$this->assertNotEmpty($model->read(null, 1));
3851
3852
		$this->assertTrue($this->Dbo->begin());
3853
		$this->assertTrue($model->delete(1));
3854
		$this->assertEmpty($model->read(null, 1));
3855
		$this->assertTrue($this->Dbo->rollback());
3856
		$this->assertNotEmpty($model->read(null, 1));
3857
3858
		$this->assertTrue($this->Dbo->begin());
3859
		$this->assertTrue($model->delete(1));
3860
		$this->assertEmpty($model->read(null, 1));
3861
		$this->assertTrue($this->Dbo->commit());
3862
		$this->assertEmpty($model->read(null, 1));
3863
3864
		$this->assertTrue($this->Dbo->rollback());
3865
		$this->assertNotEmpty($model->read(null, 1));
3866
3867
		$this->Dbo->useNestedTransactions = $nested;
3868
	}
3869
3870
}
3871