Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 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 bool
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', 'core.unsigned'
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
 * @return void
200
 */
201
	public function testTinyintCasting() {
202
		$this->Dbo->cacheSources = false;
203
		$tableName = 'tinyint_' . uniqid();
204
		$this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
205
 
206
		$this->model = new CakeTestModel(array(
207
			'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
208
		));
209
 
210
		$result = $this->model->schema();
211
		$this->assertEquals('boolean', $result['bool']['type']);
212
		$this->assertEquals('integer', $result['small_int']['type']);
213
 
214
		$this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
215
		$result = $this->model->find('first');
216
		$this->assertTrue($result['Tinyint']['bool']);
217
		$this->assertSame($result['Tinyint']['small_int'], '5');
218
		$this->model->deleteAll(true);
219
 
220
		$this->assertTrue((bool)$this->model->save(array('bool' => 0, 'small_int' => 100)));
221
		$result = $this->model->find('first');
222
		$this->assertFalse($result['Tinyint']['bool']);
223
		$this->assertSame($result['Tinyint']['small_int'], '100');
224
		$this->model->deleteAll(true);
225
 
226
		$this->assertTrue((bool)$this->model->save(array('bool' => true, 'small_int' => 0)));
227
		$result = $this->model->find('first');
228
		$this->assertTrue($result['Tinyint']['bool']);
229
		$this->assertSame($result['Tinyint']['small_int'], '0');
230
		$this->model->deleteAll(true);
231
 
232
		$this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
233
	}
234
 
235
/**
236
 * testLastAffected method
237
 *
238
 * @return void
239
 */
240
	public function testLastAffected() {
241
		$this->Dbo->cacheSources = false;
242
		$tableName = 'tinyint_' . uniqid();
243
		$this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
244
 
245
		$this->model = new CakeTestModel(array(
246
			'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
247
		));
248
 
249
		$this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
250
		$this->assertEquals(1, $this->model->find('count'));
251
		$this->model->deleteAll(true);
252
		$result = $this->Dbo->lastAffected();
253
		$this->assertEquals(1, $result);
254
		$this->assertEquals(0, $this->model->find('count'));
255
 
256
		$this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
257
	}
258
 
259
/**
260
 * testIndexDetection method
261
 *
262
 * @group indices
263
 * @return void
264
 */
265
	public function testIndexDetection() {
266
		$this->Dbo->cacheSources = false;
267
 
268
		$name = $this->Dbo->fullTableName('simple');
269
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
270
		$expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
271
		$result = $this->Dbo->index('simple', false);
272
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
273
		$this->assertEquals($expected, $result);
274
 
275
		$name = $this->Dbo->fullTableName('bigint');
276
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id bigint(20) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
277
		$expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
278
		$result = $this->Dbo->index('bigint', false);
279
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
280
		$this->assertEquals($expected, $result);
281
 
282
		$name = $this->Dbo->fullTableName('with_a_key');
283
		$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` ));');
284
		$expected = array(
285
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
286
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
287
		);
288
		$result = $this->Dbo->index('with_a_key', false);
289
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
290
		$this->assertEquals($expected, $result);
291
 
292
		$name = $this->Dbo->fullTableName('with_two_keys');
293
		$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` ));');
294
		$expected = array(
295
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
296
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
297
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
298
		);
299
		$result = $this->Dbo->index('with_two_keys', false);
300
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
301
		$this->assertEquals($expected, $result);
302
 
303
		$name = $this->Dbo->fullTableName('with_compound_keys');
304
		$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` ));');
305
		$expected = array(
306
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
307
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
308
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
309
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
310
		);
311
		$result = $this->Dbo->index('with_compound_keys', false);
312
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
313
		$this->assertEquals($expected, $result);
314
 
315
		$name = $this->Dbo->fullTableName('with_multiple_compound_keys');
316
		$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` ));');
317
		$expected = array(
318
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
319
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
320
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
321
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
322
			'other_way' => array('column' => array('small_int', 'bool'), 'unique' => 0),
323
		);
324
		$result = $this->Dbo->index('with_multiple_compound_keys', false);
325
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
326
		$this->assertEquals($expected, $result);
327
 
328
		$name = $this->Dbo->fullTableName('with_fulltext');
329
		$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;');
330
		$expected = array(
331
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
332
			'MyFtIndex' => array('column' => array('name', 'description'), 'type' => 'fulltext')
333
		);
334
		$result = $this->Dbo->index('with_fulltext', false);
335
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
336
		$this->assertEquals($expected, $result);
337
 
338
		$name = $this->Dbo->fullTableName('with_text_index');
339
		$this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, text_field text, primary key(id), KEY `text_index` ( `text_field`(20) ));');
340
		$expected = array(
341
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
342
			'text_index' => array('column' => 'text_field', 'unique' => 0, 'length' => array('text_field' => 20)),
343
		);
344
		$result = $this->Dbo->index('with_text_index', false);
345
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
346
		$this->assertEquals($expected, $result);
347
 
348
		$name = $this->Dbo->fullTableName('with_compound_text_index');
349
		$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) ));');
350
		$expected = array(
351
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
352
			'text_index' => array('column' => array('text_field1', 'text_field2'), 'unique' => 0, 'length' => array('text_field1' => 20, 'text_field2' => 20)),
353
		);
354
		$result = $this->Dbo->index('with_compound_text_index', false);
355
		$this->Dbo->rawQuery('DROP TABLE ' . $name);
356
		$this->assertEquals($expected, $result);
357
	}
358
 
359
/**
360
 * testBuildColumn method
361
 *
362
 * @return void
363
 */
364
	public function testBuildColumn() {
365
		$restore = $this->Dbo->columns;
366
		$this->Dbo->columns = array('varchar(255)' => 1);
367
		$data = array(
368
			'name' => 'testName',
369
			'type' => 'varchar(255)',
370
			'default',
371
			'null' => true,
372
			'key',
373
			'comment' => 'test'
374
		);
375
		$result = $this->Dbo->buildColumn($data);
376
		$expected = '`testName`  DEFAULT NULL COMMENT \'test\'';
377
		$this->assertEquals($expected, $result);
378
 
379
		$data = array(
380
			'name' => 'testName',
381
			'type' => 'varchar(255)',
382
			'default',
383
			'null' => true,
384
			'key',
385
			'charset' => 'utf8',
386
			'collate' => 'utf8_unicode_ci'
387
		);
388
		$result = $this->Dbo->buildColumn($data);
389
		$expected = '`testName`  CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL';
390
		$this->assertEquals($expected, $result);
391
		$this->Dbo->columns = $restore;
392
	}
393
 
394
/**
395
 * MySQL 4.x returns index data in a different format,
396
 * Using a mock ensure that MySQL 4.x output is properly parsed.
397
 *
398
 * @group indices
399
 * @return void
400
 */
401
	public function testIndexOnMySQL4Output() {
402
		$name = $this->Dbo->fullTableName('simple');
403
 
404
		$mockDbo = $this->getMock('Mysql', array('connect', '_execute', 'getVersion'));
405
		$columnData = array(
406
			array('0' => array(
407
				'Table' => 'with_compound_keys',
408
				'Non_unique' => '0',
409
				'Key_name' => 'PRIMARY',
410
				'Seq_in_index' => '1',
411
				'Column_name' => 'id',
412
				'Collation' => 'A',
413
				'Cardinality' => '0',
414
				'Sub_part' => null,
415
				'Packed' => null,
416
				'Null' => '',
417
				'Index_type' => 'BTREE',
418
				'Comment' => ''
419
			)),
420
			array('0' => array(
421
				'Table' => 'with_compound_keys',
422
				'Non_unique' => '1',
423
				'Key_name' => 'pointless_bool',
424
				'Seq_in_index' => '1',
425
				'Column_name' => 'bool',
426
				'Collation' => 'A',
427
				'Cardinality' => null,
428
				'Sub_part' => null,
429
				'Packed' => null,
430
				'Null' => 'YES',
431
				'Index_type' => 'BTREE',
432
				'Comment' => ''
433
			)),
434
			array('0' => array(
435
				'Table' => 'with_compound_keys',
436
				'Non_unique' => '1',
437
				'Key_name' => 'pointless_small_int',
438
				'Seq_in_index' => '1',
439
				'Column_name' => 'small_int',
440
				'Collation' => 'A',
441
				'Cardinality' => null,
442
				'Sub_part' => null,
443
				'Packed' => null,
444
				'Null' => 'YES',
445
				'Index_type' => 'BTREE',
446
				'Comment' => ''
447
			)),
448
			array('0' => array(
449
				'Table' => 'with_compound_keys',
450
				'Non_unique' => '1',
451
				'Key_name' => 'one_way',
452
				'Seq_in_index' => '1',
453
				'Column_name' => 'bool',
454
				'Collation' => 'A',
455
				'Cardinality' => null,
456
				'Sub_part' => null,
457
				'Packed' => null,
458
				'Null' => 'YES',
459
				'Index_type' => 'BTREE',
460
				'Comment' => ''
461
			)),
462
			array('0' => array(
463
				'Table' => 'with_compound_keys',
464
				'Non_unique' => '1',
465
				'Key_name' => 'one_way',
466
				'Seq_in_index' => '2',
467
				'Column_name' => 'small_int',
468
				'Collation' => 'A',
469
				'Cardinality' => null,
470
				'Sub_part' => null,
471
				'Packed' => null,
472
				'Null' => 'YES',
473
				'Index_type' => 'BTREE',
474
				'Comment' => ''
475
			))
476
		);
477
 
478
		$mockDbo->expects($this->once())->method('getVersion')->will($this->returnValue('4.1'));
479
		$resultMock = $this->getMock('PDOStatement', array('fetch'));
480
		$mockDbo->expects($this->once())
481
			->method('_execute')
482
			->with('SHOW INDEX FROM ' . $name)
483
			->will($this->returnValue($resultMock));
484
 
485
		foreach ($columnData as $i => $data) {
486
			$resultMock->expects($this->at($i))->method('fetch')->will($this->returnValue((object)$data));
487
		}
488
 
489
		$result = $mockDbo->index($name, false);
490
		$expected = array(
491
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
492
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
493
			'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
494
			'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
495
		);
496
		$this->assertEquals($expected, $result);
497
	}
498
 
499
/**
500
 * testColumn method
501
 *
502
 * @return void
503
 */
504
	public function testColumn() {
505
		$result = $this->Dbo->column('varchar(50)');
506
		$expected = 'string';
507
		$this->assertEquals($expected, $result);
508
 
509
		$result = $this->Dbo->column('text');
510
		$expected = 'text';
511
		$this->assertEquals($expected, $result);
512
 
513
		$result = $this->Dbo->column('int(11)');
514
		$expected = 'integer';
515
		$this->assertEquals($expected, $result);
516
 
517
		$result = $this->Dbo->column('int(11) unsigned');
518
		$expected = 'integer';
519
		$this->assertEquals($expected, $result);
520
 
521
		$result = $this->Dbo->column('bigint(20)');
522
		$expected = 'biginteger';
523
		$this->assertEquals($expected, $result);
524
 
525
		$result = $this->Dbo->column('tinyint(1)');
526
		$expected = 'boolean';
527
		$this->assertEquals($expected, $result);
528
 
529
		$result = $this->Dbo->column('boolean');
530
		$expected = 'boolean';
531
		$this->assertEquals($expected, $result);
532
 
533
		$result = $this->Dbo->column('float');
534
		$expected = 'float';
535
		$this->assertEquals($expected, $result);
536
 
537
		$result = $this->Dbo->column('float unsigned');
538
		$expected = 'float';
539
		$this->assertEquals($expected, $result);
540
 
541
		$result = $this->Dbo->column('double unsigned');
542
		$expected = 'float';
543
		$this->assertEquals($expected, $result);
544
 
545
		$result = $this->Dbo->column('decimal');
546
		$expected = 'decimal';
547
		$this->assertEquals($expected, $result);
548
 
549
		$result = $this->Dbo->column('numeric');
550
		$expected = 'decimal';
551
		$this->assertEquals($expected, $result);
552
 
553
		$result = $this->Dbo->column('decimal(14,7) unsigned');
554
		$expected = 'decimal';
555
		$this->assertEquals($expected, $result);
556
	}
557
 
558
/**
559
 * testAlterSchemaIndexes method
560
 *
561
 * @group indices
562
 * @return void
563
 */
564
	public function testAlterSchemaIndexes() {
565
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
566
		$table = $this->Dbo->fullTableName('altertest');
567
 
568
		$schemaA = new CakeSchema(array(
569
			'name' => 'AlterTest1',
570
			'connection' => 'test',
571
			'altertest' => array(
572
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
573
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
574
				'group1' => array('type' => 'integer', 'null' => true),
575
				'group2' => array('type' => 'integer', 'null' => true)
576
		)));
577
		$result = $this->Dbo->createSchema($schemaA);
578
		$this->assertContains('`id` int(11) DEFAULT 0 NOT NULL,', $result);
579
		$this->assertContains('`name` varchar(50) NOT NULL,', $result);
580
		$this->assertContains('`group1` int(11) DEFAULT NULL', $result);
581
		$this->assertContains('`group2` int(11) DEFAULT NULL', $result);
582
 
583
		//Test that the string is syntactically correct
584
		$query = $this->Dbo->getConnection()->prepare($result);
585
		$this->assertEquals($query->queryString, $result);
586
 
587
		$schemaB = new CakeSchema(array(
588
			'name' => 'AlterTest2',
589
			'connection' => 'test',
590
			'altertest' => array(
591
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
592
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
593
				'group1' => array('type' => 'integer', 'null' => true),
594
				'group2' => array('type' => 'integer', 'null' => true),
595
				'indexes' => array(
596
					'name_idx' => array('column' => 'name', 'unique' => 0),
597
					'group_idx' => array('column' => 'group1', 'unique' => 0),
598
					'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
599
					'PRIMARY' => array('column' => 'id', 'unique' => 1))
600
		)));
601
 
602
		$result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
603
		$this->assertContains("ALTER TABLE $table", $result);
604
		$this->assertContains('ADD KEY `name_idx` (`name`),', $result);
605
		$this->assertContains('ADD KEY `group_idx` (`group1`),', $result);
606
		$this->assertContains('ADD KEY `compound_idx` (`group1`, `group2`),', $result);
607
		$this->assertContains('ADD PRIMARY KEY  (`id`);', $result);
608
 
609
		//Test that the string is syntactically correct
610
		$query = $this->Dbo->getConnection()->prepare($result);
611
		$this->assertEquals($query->queryString, $result);
612
 
613
		// Change three indexes, delete one and add another one
614
		$schemaC = new CakeSchema(array(
615
			'name' => 'AlterTest3',
616
			'connection' => 'test',
617
			'altertest' => array(
618
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
619
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
620
				'group1' => array('type' => 'integer', 'null' => true),
621
				'group2' => array('type' => 'integer', 'null' => true),
622
				'indexes' => array(
623
					'name_idx' => array('column' => 'name', 'unique' => 1),
624
					'group_idx' => array('column' => 'group2', 'unique' => 0),
625
					'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
626
					'id_name_idx' => array('column' => array('id', 'name'), 'unique' => 0))
627
		)));
628
 
629
		$result = $this->Dbo->alterSchema($schemaC->compare($schemaB));
630
		$this->assertContains("ALTER TABLE $table", $result);
631
		$this->assertContains('DROP PRIMARY KEY,', $result);
632
		$this->assertContains('DROP KEY `name_idx`,', $result);
633
		$this->assertContains('DROP KEY `group_idx`,', $result);
634
		$this->assertContains('DROP KEY `compound_idx`,', $result);
635
		$this->assertContains('ADD KEY `id_name_idx` (`id`, `name`),', $result);
636
		$this->assertContains('ADD UNIQUE KEY `name_idx` (`name`),', $result);
637
		$this->assertContains('ADD KEY `group_idx` (`group2`),', $result);
638
		$this->assertContains('ADD KEY `compound_idx` (`group2`, `group1`);', $result);
639
 
640
		$query = $this->Dbo->getConnection()->prepare($result);
641
		$this->assertEquals($query->queryString, $result);
642
 
643
		// Compare us to ourself.
644
		$this->assertEquals(array(), $schemaC->compare($schemaC));
645
 
646
		// Drop the indexes
647
		$result = $this->Dbo->alterSchema($schemaA->compare($schemaC));
648
 
649
		$this->assertContains("ALTER TABLE $table", $result);
650
		$this->assertContains('DROP KEY `name_idx`,', $result);
651
		$this->assertContains('DROP KEY `group_idx`,', $result);
652
		$this->assertContains('DROP KEY `compound_idx`,', $result);
653
		$this->assertContains('DROP KEY `id_name_idx`;', $result);
654
 
655
		$query = $this->Dbo->getConnection()->prepare($result);
656
		$this->assertEquals($query->queryString, $result);
657
	}
658
 
659
/**
660
 * test saving and retrieval of blobs
661
 *
662
 * @return void
663
 */
664
	public function testBlobSaving() {
665
		$this->loadFixtures('BinaryTest');
666
		$this->Dbo->cacheSources = false;
667
		$data = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
668
 
669
		$model = new CakeTestModel(array('name' => 'BinaryTest', 'ds' => 'test'));
670
		$model->save(compact('data'));
671
 
672
		$result = $model->find('first');
673
		$this->assertEquals($data, $result['BinaryTest']['data']);
674
	}
675
 
676
/**
677
 * test altering the table settings with schema.
678
 *
679
 * @return void
680
 */
681
	public function testAlteringTableParameters() {
682
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
683
 
684
		$schemaA = new CakeSchema(array(
685
			'name' => 'AlterTest1',
686
			'connection' => 'test',
687
			'altertest' => array(
688
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
689
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
690
				'tableParameters' => array(
691
					'charset' => 'latin1',
692
					'collate' => 'latin1_general_ci',
693
					'engine' => 'MyISAM'
694
				)
695
			)
696
		));
697
		$this->Dbo->rawQuery($this->Dbo->createSchema($schemaA));
698
		$schemaB = new CakeSchema(array(
699
			'name' => 'AlterTest1',
700
			'connection' => 'test',
701
			'altertest' => array(
702
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
703
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
704
				'tableParameters' => array(
705
					'charset' => 'utf8',
706
					'collate' => 'utf8_general_ci',
707
					'engine' => 'InnoDB'
708
				)
709
			)
710
		));
711
		$result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
712
		$this->assertContains('DEFAULT CHARSET=utf8', $result);
713
		$this->assertContains('ENGINE=InnoDB', $result);
714
		$this->assertContains('COLLATE=utf8_general_ci', $result);
715
 
716
		$this->Dbo->rawQuery($result);
717
		$result = $this->Dbo->listDetailedSources($this->Dbo->fullTableName('altertest', false, false));
718
		$this->assertEquals('utf8_general_ci', $result['Collation']);
719
		$this->assertEquals('InnoDB', $result['Engine']);
720
		$this->assertEquals('utf8', $result['charset']);
721
 
722
		$this->Dbo->rawQuery($this->Dbo->dropSchema($schemaA));
723
	}
724
 
725
/**
726
 * test alterSchema on two tables.
727
 *
728
 * @return void
729
 */
730
	public function testAlteringTwoTables() {
731
		$schema1 = new CakeSchema(array(
732
			'name' => 'AlterTest1',
733
			'connection' => 'test',
734
			'altertest' => array(
735
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
736
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
737
			),
738
			'other_table' => array(
739
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
740
				'name' => array('type' => 'string', 'null' => false, 'length' => 50),
741
			)
742
		));
743
		$schema2 = new CakeSchema(array(
744
			'name' => 'AlterTest1',
745
			'connection' => 'test',
746
			'altertest' => array(
747
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
748
				'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
749
			),
750
			'other_table' => array(
751
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
752
				'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
753
			)
754
		));
755
		$result = $this->Dbo->alterSchema($schema2->compare($schema1));
756
		$this->assertEquals(2, substr_count($result, 'field_two'), 'Too many fields');
757
	}
758
 
759
/**
760
 * testReadTableParameters method
761
 *
762
 * @return void
763
 */
764
	public function testReadTableParameters() {
765
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
766
		$tableName = 'tinyint_' . uniqid();
767
		$table = $this->Dbo->fullTableName($tableName);
768
		$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;');
769
		$result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
770
		$this->Dbo->rawQuery('DROP TABLE ' . $table);
771
		$expected = array(
772
			'charset' => 'utf8',
773
			'collate' => 'utf8_unicode_ci',
774
			'engine' => 'InnoDB');
775
		$this->assertEquals($expected, $result);
776
 
777
		$table = $this->Dbo->fullTableName($tableName);
778
		$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;');
779
		$result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
780
		$this->Dbo->rawQuery('DROP TABLE ' . $table);
781
		$expected = array(
782
			'charset' => 'cp1250',
783
			'collate' => 'cp1250_general_ci',
784
			'engine' => 'MyISAM');
785
		$this->assertEquals($expected, $result);
786
	}
787
 
788
/**
789
 * testBuildTableParameters method
790
 *
791
 * @return void
792
 */
793
	public function testBuildTableParameters() {
794
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
795
		$data = array(
796
			'charset' => 'utf8',
797
			'collate' => 'utf8_unicode_ci',
798
			'engine' => 'InnoDB');
799
		$result = $this->Dbo->buildTableParameters($data);
800
		$expected = array(
801
			'DEFAULT CHARSET=utf8',
802
			'COLLATE=utf8_unicode_ci',
803
			'ENGINE=InnoDB');
804
		$this->assertEquals($expected, $result);
805
	}
806
 
807
/**
808
 * testGetCharsetName method
809
 *
810
 * @return void
811
 */
812
	public function testGetCharsetName() {
813
		$this->Dbo->cacheSources = $this->Dbo->testing = false;
814
		$result = $this->Dbo->getCharsetName('utf8_unicode_ci');
815
		$this->assertEquals('utf8', $result);
816
		$result = $this->Dbo->getCharsetName('cp1250_general_ci');
817
		$this->assertEquals('cp1250', $result);
818
	}
819
 
820
/**
821
 * testGetCharsetNameCaching method
822
 *
823
 * @return void
824
 */
825
	public function testGetCharsetNameCaching() {
826
		$db = $this->getMock('Mysql', array('connect', '_execute', 'getVersion'));
827
		$queryResult = $this->getMock('PDOStatement');
828
 
829
		$db->expects($this->exactly(2))->method('getVersion')->will($this->returnValue('5.1'));
830
 
831
		$db->expects($this->exactly(1))
832
			->method('_execute')
833
			->with('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?', array('utf8_unicode_ci'))
834
			->will($this->returnValue($queryResult));
835
 
836
		$queryResult->expects($this->once())
837
			->method('fetch')
838
			->with(PDO::FETCH_ASSOC)
839
			->will($this->returnValue(array('CHARACTER_SET_NAME' => 'utf8')));
840
 
841
		$result = $db->getCharsetName('utf8_unicode_ci');
842
		$this->assertEquals('utf8', $result);
843
 
844
		$result = $db->getCharsetName('utf8_unicode_ci');
845
		$this->assertEquals('utf8', $result);
846
	}
847
 
848
/**
849
 * test that changing the virtualFieldSeparator allows for __ fields.
850
 *
851
 * @return void
852
 */
853
	public function testVirtualFieldSeparators() {
854
		$this->loadFixtures('BinaryTest');
855
		$model = new CakeTestModel(array('table' => 'binary_tests', 'ds' => 'test', 'name' => 'BinaryTest'));
856
		$model->virtualFields = array(
857
			'other__field' => 'SUM(id)'
858
		);
859
 
860
		$this->Dbo->virtualFieldSeparator = '_$_';
861
		$result = $this->Dbo->fields($model, null, array('data', 'other__field'));
862
 
863
		$expected = array('`BinaryTest`.`data`', '(SUM(id)) AS  `BinaryTest_$_other__field`');
864
		$this->assertEquals($expected, $result);
865
	}
866
 
867
/**
868
 * Test describe() on a fixture.
869
 *
870
 * @return void
871
 */
872
	public function testDescribe() {
873
		$this->loadFixtures('Apple');
874
 
875
		$model = new Apple();
876
		$result = $this->Dbo->describe($model);
877
 
878
		$this->assertTrue(isset($result['id']));
879
		$this->assertTrue(isset($result['color']));
880
 
881
		$result = $this->Dbo->describe($model->useTable);
882
 
883
		$this->assertTrue(isset($result['id']));
884
		$this->assertTrue(isset($result['color']));
885
	}
886
 
887
/**
888
 * test that a describe() gets additional fieldParameters
889
 *
890
 * @return void
891
 */
892
	public function testDescribeGettingFieldParameters() {
893
		$schema = new CakeSchema(array(
894
			'connection' => 'test',
895
			'testdescribes' => array(
896
				'id' => array('type' => 'integer', 'key' => 'primary'),
897
				'stringy' => array(
898
					'type' => 'string',
899
					'null' => true,
900
					'charset' => 'cp1250',
901
					'collate' => 'cp1250_general_ci',
902
				),
903
				'other_col' => array(
904
					'type' => 'string',
905
					'null' => false,
906
					'charset' => 'latin1',
907
					'comment' => 'Test Comment'
908
				)
909
			)
910
		));
911
 
912
		$this->Dbo->execute($this->Dbo->createSchema($schema));
913
		$model = new CakeTestModel(array('table' => 'testdescribes', 'name' => 'Testdescribes'));
914
		$result = $model->getDataSource()->describe($model);
915
		$this->Dbo->execute($this->Dbo->dropSchema($schema));
916
 
917
		$this->assertEquals('cp1250_general_ci', $result['stringy']['collate']);
918
		$this->assertEquals('cp1250', $result['stringy']['charset']);
919
		$this->assertEquals('Test Comment', $result['other_col']['comment']);
920
	}
921
 
922
/**
923
 * Test that two columns with key => primary doesn't create invalid sql.
924
 *
925
 * @return void
926
 */
927
	public function testTwoColumnsWithPrimaryKey() {
928
		$schema = new CakeSchema(array(
929
			'connection' => 'test',
930
			'roles_users' => array(
931
				'role_id' => array(
932
					'type' => 'integer',
933
					'null' => false,
934
					'default' => null,
935
					'key' => 'primary'
936
				),
937
				'user_id' => array(
938
					'type' => 'integer',
939
					'null' => false,
940
					'default' => null,
941
					'key' => 'primary'
942
				),
943
				'indexes' => array(
944
					'user_role_index' => array(
945
						'column' => array('role_id', 'user_id'),
946
						'unique' => 1
947
					),
948
					'user_index' => array(
949
						'column' => 'user_id',
950
						'unique' => 0
951
					)
952
				),
953
			)
954
		));
955
 
956
		$result = $this->Dbo->createSchema($schema);
957
		$this->assertContains('`role_id` int(11) NOT NULL,', $result);
958
		$this->assertContains('`user_id` int(11) NOT NULL,', $result);
959
	}
960
 
961
/**
962
 * Test that the primary flag is handled correctly.
963
 *
964
 * @return void
965
 */
966
	public function testCreateSchemaAutoPrimaryKey() {
967
		$schema = new CakeSchema();
968
		$schema->tables = array(
969
			'no_indexes' => array(
970
				'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
971
				'data' => array('type' => 'integer', 'null' => false),
972
				'indexes' => array(),
973
			)
974
		);
975
		$result = $this->Dbo->createSchema($schema, 'no_indexes');
976
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
977
		$this->assertNotContains('UNIQUE KEY', $result);
978
 
979
		$schema->tables = array(
980
			'primary_index' => array(
981
				'id' => array('type' => 'integer', 'null' => false),
982
				'data' => array('type' => 'integer', 'null' => false),
983
				'indexes' => array(
984
					'PRIMARY' => array('column' => 'id', 'unique' => 1),
985
					'some_index' => array('column' => 'data', 'unique' => 1)
986
				),
987
			)
988
		);
989
		$result = $this->Dbo->createSchema($schema, 'primary_index');
990
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
991
		$this->assertContains('UNIQUE KEY `some_index` (`data`)', $result);
992
 
993
		$schema->tables = array(
994
			'primary_flag_has_index' => array(
995
				'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
996
				'data' => array('type' => 'integer', 'null' => false),
997
				'indexes' => array(
998
					'some_index' => array('column' => 'data', 'unique' => 1)
999
				),
1000
			)
1001
		);
1002
		$result = $this->Dbo->createSchema($schema, 'primary_flag_has_index');
1003
		$this->assertContains('PRIMARY KEY  (`id`)', $result);
1004
		$this->assertContains('UNIQUE KEY `some_index` (`data`)', $result);
1005
	}
1006
 
1007
/**
1008
 * Tests that listSources method sends the correct query and parses the result accordingly
1009
 * @return void
1010
 */
1011
	public function testListSources() {
1012
		$db = $this->getMock('Mysql', array('connect', '_execute'));
1013
		$queryResult = $this->getMock('PDOStatement');
1014
		$db->expects($this->once())
1015
			->method('_execute')
1016
			->with('SHOW TABLES FROM `cake`')
1017
			->will($this->returnValue($queryResult));
1018
		$queryResult->expects($this->at(0))
1019
			->method('fetch')
1020
			->will($this->returnValue(array('cake_table')));
1021
		$queryResult->expects($this->at(1))
1022
			->method('fetch')
1023
			->will($this->returnValue(array('another_table')));
1024
		$queryResult->expects($this->at(2))
1025
			->method('fetch')
1026
			->will($this->returnValue(null));
1027
 
1028
		$tables = $db->listSources();
1029
		$this->assertEquals(array('cake_table', 'another_table'), $tables);
1030
	}
1031
 
1032
/**
1033
 * test that listDetailedSources with a named table that doesn't exist.
1034
 *
1035
 * @return void
1036
 */
1037
	public function testListDetailedSourcesNamed() {
1038
		$this->loadFixtures('Apple');
1039
 
1040
		$result = $this->Dbo->listDetailedSources('imaginary');
1041
		$this->assertEquals(array(), $result, 'Should be empty when table does not exist.');
1042
 
1043
		$result = $this->Dbo->listDetailedSources();
1044
		$tableName = $this->Dbo->fullTableName('apples', false, false);
1045
		$this->assertTrue(isset($result[$tableName]), 'Key should exist');
1046
	}
1047
 
1048
/**
1049
 * Tests that getVersion method sends the correct query for getting the mysql version
1050
 * @return void
1051
 */
1052
	public function testGetVersion() {
1053
		$version = $this->Dbo->getVersion();
1054
		$this->assertTrue(is_string($version));
1055
	}
1056
 
1057
/**
1058
 * Tests that getVersion method sends the correct query for getting the client encoding
1059
 * @return void
1060
 */
1061
	public function testGetEncoding() {
1062
		$db = $this->getMock('Mysql', array('connect', '_execute'));
1063
		$queryResult = $this->getMock('PDOStatement');
1064
 
1065
		$db->expects($this->once())
1066
			->method('_execute')
1067
			->with('SHOW VARIABLES LIKE ?', array('character_set_client'))
1068
			->will($this->returnValue($queryResult));
1069
		$result = new StdClass;
1070
		$result->Value = 'utf-8';
1071
		$queryResult->expects($this->once())
1072
			->method('fetchObject')
1073
			->will($this->returnValue($result));
1074
 
1075
		$encoding = $db->getEncoding();
1076
		$this->assertEquals('utf-8', $encoding);
1077
	}
1078
 
1079
/**
1080
 * testFieldDoubleEscaping method
1081
 *
1082
 * @return void
1083
 */
1084
	public function testFieldDoubleEscaping() {
1085
		$db = $this->Dbo->config['database'];
1086
		$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1087
		$test->config['database'] = $db;
1088
 
1089
		$this->Model = $this->getMock('Article2', array('getDataSource'));
1090
		$this->Model->alias = 'Article';
1091
		$this->Model->expects($this->any())
1092
			->method('getDataSource')
1093
			->will($this->returnValue($test));
1094
 
1095
		$this->assertEquals('`Article`.`id`', $this->Model->escapeField());
1096
		$result = $test->fields($this->Model, null, $this->Model->escapeField());
1097
		$this->assertEquals(array('`Article`.`id`'), $result);
1098
 
1099
		$test->expects($this->at(0))->method('execute')
1100
			->with('SELECT `Article`.`id` FROM ' . $test->fullTableName('articles') . ' AS `Article`   WHERE 1 = 1');
1101
 
1102
		$result = $test->read($this->Model, array(
1103
			'fields' => $this->Model->escapeField(),
1104
			'conditions' => null,
1105
			'recursive' => -1
1106
		));
1107
 
1108
		$test->startQuote = '[';
1109
		$test->endQuote = ']';
1110
		$this->assertEquals('[Article].[id]', $this->Model->escapeField());
1111
 
1112
		$result = $test->fields($this->Model, null, $this->Model->escapeField());
1113
		$this->assertEquals(array('[Article].[id]'), $result);
1114
 
1115
		$test->expects($this->at(0))->method('execute')
1116
			->with('SELECT [Article].[id] FROM ' . $test->fullTableName('articles') . ' AS [Article]   WHERE 1 = 1');
1117
		$result = $test->read($this->Model, array(
1118
			'fields' => $this->Model->escapeField(),
1119
			'conditions' => null,
1120
			'recursive' => -1
1121
		));
1122
	}
1123
 
1124
/**
1125
 * testGenerateAssociationQuerySelfJoin method
1126
 *
1127
 * @return void
1128
 */
1129
	public function testGenerateAssociationQuerySelfJoin() {
1130
		$this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1131
		$this->startTime = microtime(true);
1132
		$this->Model = new Article2();
1133
		$this->_buildRelatedModels($this->Model);
1134
		$this->_buildRelatedModels($this->Model->Category2);
1135
		$this->Model->Category2->ChildCat = new Category2();
1136
		$this->Model->Category2->ParentCat = new Category2();
1137
 
1138
		$queryData = array();
1139
 
1140
		foreach ($this->Model->Category2->associations() as $type) {
1141
			foreach ($this->Model->Category2->{$type} as $assoc => $assocData) {
1142
				$linkModel = $this->Model->Category2->{$assoc};
1143
				$external = isset($assocData['external']);
1144
 
1145
				if ($this->Model->Category2->alias === $linkModel->alias &&
1146
					$type !== 'hasAndBelongsToMany' &&
1147
					$type !== 'hasMany'
1148
				) {
1149
					$result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external);
1150
					$this->assertFalse(empty($result));
1151
				} else {
1152
					if ($this->Model->Category2->useDbConfig === $linkModel->useDbConfig) {
1153
						$result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external);
1154
						$this->assertFalse(empty($result));
1155
					}
1156
				}
1157
			}
1158
		}
1159
 
1160
		$query = $this->Dbo->buildAssociationQuery($this->Model->Category2, $queryData);
1161
		$this->assertRegExp('/^SELECT\s+(.+)FROM(.+)`Category2`\.`group_id`\s+=\s+`Group`\.`id`\)\s+LEFT JOIN(.+)WHERE\s+1 = 1\s*$/', $query);
1162
 
1163
		$this->Model = new TestModel4();
1164
		$this->Model->schema();
1165
		$this->_buildRelatedModels($this->Model);
1166
 
1167
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
1168
		$queryData = array();
1169
 
1170
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1171
 
1172
		$_queryData = $queryData;
1173
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1174
		$this->assertTrue($result);
1175
 
1176
		$expected = array(
1177
			'conditions' => array(),
1178
			'fields' => array(
1179
				'`TestModel4`.`id`',
1180
				'`TestModel4`.`name`',
1181
				'`TestModel4`.`created`',
1182
				'`TestModel4`.`updated`',
1183
				'`TestModel4Parent`.`id`',
1184
				'`TestModel4Parent`.`name`',
1185
				'`TestModel4Parent`.`created`',
1186
				'`TestModel4Parent`.`updated`'
1187
			),
1188
			'joins' => array(
1189
				array(
1190
					'table' => $this->Dbo->fullTableName($this->Model),
1191
					'alias' => 'TestModel4Parent',
1192
					'type' => 'LEFT',
1193
					'conditions' => '`TestModel4`.`parent_id` = `TestModel4Parent`.`id`'
1194
				)
1195
			),
1196
			'order' => array(),
1197
			'limit' => array(),
1198
			'offset' => array(),
1199
			'group' => array(),
1200
			'callbacks' => null
1201
		);
1202
		$queryData['joins'][0]['table'] = $this->Dbo->fullTableName($queryData['joins'][0]['table']);
1203
		$this->assertEquals($expected, $queryData);
1204
 
1205
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1206
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
1207
		$this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
1208
		$this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
1209
		$this->assertRegExp('/\s+WHERE\s+1 = 1$/', $result);
1210
 
1211
		$params['assocData']['type'] = 'INNER';
1212
		$this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER';
1213
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $_queryData, $params['external']);
1214
		$this->assertTrue($result);
1215
		$this->assertEquals('INNER', $_queryData['joins'][0]['type']);
1216
	}
1217
 
1218
/**
1219
 * buildRelatedModels method
1220
 *
1221
 * @param Model $model
1222
 * @return void
1223
 */
1224
	protected function _buildRelatedModels(Model $model) {
1225
		foreach ($model->associations() as $type) {
1226
			foreach ($model->{$type} as $assocData) {
1227
				if (is_string($assocData)) {
1228
					$className = $assocData;
1229
				} elseif (isset($assocData['className'])) {
1230
					$className = $assocData['className'];
1231
				}
1232
				$model->$className = new $className();
1233
				$model->$className->schema();
1234
			}
1235
		}
1236
	}
1237
 
1238
/**
1239
 * &_prepareAssociationQuery method
1240
 *
1241
 * @param Model $model
1242
 * @param array $queryData
1243
 * @param array $binding
1244
 * @return void
1245
 */
1246
	protected function &_prepareAssociationQuery(Model $model, &$queryData, $binding) {
1247
		$type = $binding['type'];
1248
		$assoc = $binding['model'];
1249
		$assocData = $model->{$type}[$assoc];
1250
		$className = $assocData['className'];
1251
 
1252
		$linkModel = $model->{$className};
1253
		$external = isset($assocData['external']);
1254
		$queryData = $this->_scrubQueryData($queryData);
1255
 
1256
		$result = array_merge(array('linkModel' => &$linkModel), compact('type', 'assoc', 'assocData', 'external'));
1257
		return $result;
1258
	}
1259
 
1260
/**
1261
 * Helper method copied from DboSource::_scrubQueryData()
1262
 *
1263
 * @param array $data
1264
 * @return array
1265
 */
1266
	protected function _scrubQueryData($data) {
1267
		static $base = null;
1268
		if ($base === null) {
1269
			$base = array_fill_keys(array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group'), array());
1270
			$base['callbacks'] = null;
1271
		}
1272
		return (array)$data + $base;
1273
	}
1274
 
1275
/**
1276
 * test that read() places provided joins after the generated ones.
1277
 *
1278
 * @return void
1279
 */
1280
	public function testReadCustomJoinsAfterGeneratedJoins() {
1281
		$db = $this->Dbo->config['database'];
1282
		$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1283
		$test->config['database'] = $db;
1284
 
1285
		$this->Model = $this->getMock('TestModel9', array('getDataSource'));
1286
		$this->Model->expects($this->any())
1287
			->method('getDataSource')
1288
			->will($this->returnValue($test));
1289
 
1290
		$this->Model->TestModel8 = $this->getMock('TestModel8', array('getDataSource'));
1291
		$this->Model->TestModel8->expects($this->any())
1292
			->method('getDataSource')
1293
			->will($this->returnValue($test));
1294
 
1295
		$model8Table = $test->fullTableName($this->Model->TestModel8);
1296
		$usersTable = $test->fullTableName('users');
1297
 
1298
		$search = "LEFT JOIN $model8Table AS `TestModel8` ON " .
1299
			"(`TestModel8`.`name` != 'larry' AND `TestModel9`.`test_model8_id` = `TestModel8`.`id`) " .
1300
			"LEFT JOIN $usersTable AS `User` ON (`TestModel9`.`id` = `User`.`test_id`)";
1301
 
1302
		$test->expects($this->at(0))->method('execute')
1303
			->with($this->stringContains($search));
1304
 
1305
		$test->read($this->Model, array(
1306
			'joins' => array(
1307
				array(
1308
					'table' => 'users',
1309
					'alias' => 'User',
1310
					'type' => 'LEFT',
1311
					'conditions' => array('TestModel9.id = User.test_id')
1312
				)
1313
			),
1314
			'recursive' => 1
1315
		));
1316
	}
1317
 
1318
/**
1319
 * testGenerateInnerJoinAssociationQuery method
1320
 *
1321
 * @return void
1322
 */
1323
	public function testGenerateInnerJoinAssociationQuery() {
1324
		$db = $this->Dbo->config['database'];
1325
		$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
1326
		$test->config['database'] = $db;
1327
 
1328
		$this->Model = $this->getMock('TestModel9', array('getDataSource'));
1329
		$this->Model->expects($this->any())
1330
			->method('getDataSource')
1331
			->will($this->returnValue($test));
1332
 
1333
		$this->Model->TestModel8 = $this->getMock('TestModel8', array('getDataSource'));
1334
		$this->Model->TestModel8->expects($this->any())
1335
			->method('getDataSource')
1336
			->will($this->returnValue($test));
1337
 
1338
		$testModel8Table = $this->Model->TestModel8->getDataSource()->fullTableName($this->Model->TestModel8);
1339
 
1340
		$test->expects($this->at(0))->method('execute')
1341
			->with($this->stringContains('`TestModel9` LEFT JOIN ' . $testModel8Table));
1342
 
1343
		$test->expects($this->at(1))->method('execute')
1344
			->with($this->stringContains('TestModel9` INNER JOIN ' . $testModel8Table));
1345
 
1346
		$test->read($this->Model, array('recursive' => 1));
1347
		$this->Model->belongsTo['TestModel8']['type'] = 'INNER';
1348
		$test->read($this->Model, array('recursive' => 1));
1349
	}
1350
 
1351
/**
1352
 * testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding method
1353
 *
1354
 * @return void
1355
 */
1356
	public function testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding() {
1357
		$this->Model = new TestModel8();
1358
		$this->Model->schema();
1359
		$this->_buildRelatedModels($this->Model);
1360
 
1361
		$binding = array('type' => 'hasOne', 'model' => 'TestModel9');
1362
		$queryData = array();
1363
 
1364
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1365
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1366
		$this->assertTrue($result);
1367
 
1368
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1369
		$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);
1370
		$this->assertRegExp('/FROM\s+\S+`test_model8` AS `TestModel8`\s+LEFT JOIN\s+\S+`test_model9` AS `TestModel9`/', $result);
1371
		$this->assertRegExp('/\s+ON\s+\(`TestModel9`\.`name` != \'mariano\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
1372
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1373
	}
1374
 
1375
/**
1376
 * testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding method
1377
 *
1378
 * @return void
1379
 */
1380
	public function testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding() {
1381
		$this->Model = new TestModel9();
1382
		$this->Model->schema();
1383
		$this->_buildRelatedModels($this->Model);
1384
 
1385
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel8');
1386
		$queryData = array();
1387
 
1388
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1389
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1390
		$this->assertTrue($result);
1391
 
1392
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1393
		$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);
1394
		$this->assertRegExp('/FROM\s+\S+`test_model9` AS `TestModel9`\s+LEFT JOIN\s+\S+`test_model8` AS `TestModel8`/', $result);
1395
		$this->assertRegExp('/\s+ON\s+\(`TestModel8`\.`name` != \'larry\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
1396
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1397
	}
1398
 
1399
/**
1400
 * testGenerateAssociationQuerySelfJoinWithConditions method
1401
 *
1402
 * @return void
1403
 */
1404
	public function testGenerateAssociationQuerySelfJoinWithConditions() {
1405
		$this->Model = new TestModel4();
1406
		$this->Model->schema();
1407
		$this->_buildRelatedModels($this->Model);
1408
 
1409
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
1410
		$queryData = array('conditions' => array('TestModel4Parent.name !=' => 'mariano'));
1411
 
1412
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1413
 
1414
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1415
		$this->assertTrue($result);
1416
 
1417
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1418
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
1419
		$this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
1420
		$this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
1421
		$this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel4Parent`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1422
 
1423
		$this->Featured2 = new Featured2();
1424
		$this->Featured2->schema();
1425
 
1426
		$this->Featured2->bindModel(array(
1427
			'belongsTo' => array(
1428
				'ArticleFeatured2' => array(
1429
					'conditions' => 'ArticleFeatured2.published = \'Y\'',
1430
					'fields' => 'id, title, user_id, published'
1431
				)
1432
			)
1433
		));
1434
 
1435
		$this->_buildRelatedModels($this->Featured2);
1436
 
1437
		$binding = array('type' => 'belongsTo', 'model' => 'ArticleFeatured2');
1438
		$queryData = array('conditions' => array());
1439
 
1440
		$params = &$this->_prepareAssociationQuery($this->Featured2, $queryData, $binding);
1441
 
1442
		$result = $this->Dbo->generateAssociationQuery($this->Featured2, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1443
		$this->assertTrue($result);
1444
		$result = $this->Dbo->buildAssociationQuery($this->Featured2, $queryData);
1445
 
1446
		$this->assertRegExp(
1447
			'/^SELECT\s+`Featured2`\.`id`, `Featured2`\.`article_id`, `Featured2`\.`category_id`, `Featured2`\.`name`,\s+' .
1448
			'`ArticleFeatured2`\.`id`, `ArticleFeatured2`\.`title`, `ArticleFeatured2`\.`user_id`, `ArticleFeatured2`\.`published`\s+' .
1449
			'FROM\s+\S+`featured2` AS `Featured2`\s+LEFT JOIN\s+\S+`article_featured` AS `ArticleFeatured2`' .
1450
			'\s+ON\s+\(`ArticleFeatured2`.`published` = \'Y\'\s+AND\s+`Featured2`\.`article_featured2_id` = `ArticleFeatured2`\.`id`\)' .
1451
			'\s+WHERE\s+1\s+=\s+1\s*$/',
1452
			$result
1453
		);
1454
	}
1455
 
1456
/**
1457
 * testGenerateAssociationQueryHasOne method
1458
 *
1459
 * @return void
1460
 */
1461
	public function testGenerateAssociationQueryHasOne() {
1462
		$this->Model = new TestModel4();
1463
		$this->Model->schema();
1464
		$this->_buildRelatedModels($this->Model);
1465
 
1466
		$binding = array('type' => 'hasOne', 'model' => 'TestModel5');
1467
 
1468
		$queryData = array();
1469
 
1470
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1471
 
1472
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1473
		$this->assertTrue($result);
1474
 
1475
		$testModel5Table = $this->Dbo->fullTableName($this->Model->TestModel5);
1476
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1477
		$expected = ' LEFT JOIN ' . $testModel5Table . ' AS `TestModel5` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1478
		$this->assertEquals(trim($expected), trim($result));
1479
 
1480
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1481
		$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);
1482
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+/', $result);
1483
		$this->assertRegExp('/`test_model5` AS `TestModel5`\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE/', $result);
1484
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1485
	}
1486
 
1487
/**
1488
 * testGenerateAssociationQueryHasOneWithConditions method
1489
 *
1490
 * @return void
1491
 */
1492
	public function testGenerateAssociationQueryHasOneWithConditions() {
1493
		$this->Model = new TestModel4();
1494
		$this->Model->schema();
1495
		$this->_buildRelatedModels($this->Model);
1496
 
1497
		$binding = array('type' => 'hasOne', 'model' => 'TestModel5');
1498
 
1499
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1500
 
1501
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1502
 
1503
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1504
		$this->assertTrue($result);
1505
 
1506
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1507
 
1508
		$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);
1509
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model5` AS `TestModel5`/', $result);
1510
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id`\s+=\s+`TestModel4`.`id`\)\s+WHERE/', $result);
1511
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*`TestModel5`.`name`\s+!=\s+\'mariano\'\s*(?:\))?\s*$/', $result);
1512
	}
1513
 
1514
/**
1515
 * testGenerateAssociationQueryBelongsTo method
1516
 *
1517
 * @return void
1518
 */
1519
	public function testGenerateAssociationQueryBelongsTo() {
1520
		$this->Model = new TestModel5();
1521
		$this->Model->schema();
1522
		$this->_buildRelatedModels($this->Model);
1523
 
1524
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
1525
		$queryData = array();
1526
 
1527
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1528
 
1529
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1530
		$this->assertTrue($result);
1531
 
1532
		$testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
1533
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1534
		$expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1535
		$this->assertEquals(trim($expected), trim($result));
1536
 
1537
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1538
		$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);
1539
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
1540
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
1541
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1542
	}
1543
 
1544
/**
1545
 * testGenerateAssociationQueryBelongsToWithConditions method
1546
 *
1547
 * @return void
1548
 */
1549
	public function testGenerateAssociationQueryBelongsToWithConditions() {
1550
		$this->Model = new TestModel5();
1551
		$this->Model->schema();
1552
		$this->_buildRelatedModels($this->Model);
1553
 
1554
		$binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
1555
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1556
 
1557
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1558
 
1559
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1560
		$this->assertTrue($result);
1561
 
1562
		$testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
1563
		$result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
1564
		$expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
1565
		$this->assertEquals(trim($expected), trim($result));
1566
 
1567
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1568
		$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);
1569
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
1570
		$this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
1571
		$this->assertRegExp('/\s+WHERE\s+`TestModel5`.`name` != \'mariano\'\s*$/', $result);
1572
	}
1573
 
1574
/**
1575
 * testGenerateAssociationQueryHasMany method
1576
 *
1577
 * @return void
1578
 */
1579
	public function testGenerateAssociationQueryHasMany() {
1580
		$this->Model = new TestModel5();
1581
		$this->Model->schema();
1582
		$this->_buildRelatedModels($this->Model);
1583
 
1584
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1585
		$queryData = array();
1586
 
1587
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1588
 
1589
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1590
 
1591
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1592
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE/', $result);
1593
		$this->assertRegExp('/\s+WHERE\s+`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)/', $result);
1594
 
1595
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1596
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1597
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1598
		$this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
1599
	}
1600
 
1601
/**
1602
 * testGenerateAssociationQueryHasManyWithLimit method
1603
 *
1604
 * @return void
1605
 */
1606
	public function testGenerateAssociationQueryHasManyWithLimit() {
1607
		$this->Model = new TestModel5();
1608
		$this->Model->schema();
1609
		$this->_buildRelatedModels($this->Model);
1610
 
1611
		$this->Model->hasMany['TestModel6']['limit'] = 2;
1612
 
1613
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1614
		$queryData = array();
1615
 
1616
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1617
 
1618
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1619
		$this->assertRegExp(
1620
			'/^SELECT\s+' .
1621
			'`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+' .
1622
			'FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+' .
1623
			'`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)\s*' .
1624
			'LIMIT \d*' .
1625
			'\s*$/', $result
1626
		);
1627
 
1628
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1629
		$this->assertRegExp(
1630
			'/^SELECT\s+' .
1631
			'`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+' .
1632
			'FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+' .
1633
			'(?:\()?\s*1 = 1\s*(?:\))?' .
1634
			'\s*$/', $result
1635
		);
1636
	}
1637
 
1638
/**
1639
 * testGenerateAssociationQueryHasManyWithConditions method
1640
 *
1641
 * @return void
1642
 */
1643
	public function testGenerateAssociationQueryHasManyWithConditions() {
1644
		$this->Model = new TestModel5();
1645
		$this->Model->schema();
1646
		$this->_buildRelatedModels($this->Model);
1647
 
1648
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1649
		$queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
1650
 
1651
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1652
 
1653
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1654
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1655
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1656
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1657
 
1658
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1659
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1660
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1661
		$this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel5`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1662
	}
1663
 
1664
/**
1665
 * testGenerateAssociationQueryHasManyWithOffsetAndLimit method
1666
 *
1667
 * @return void
1668
 */
1669
	public function testGenerateAssociationQueryHasManyWithOffsetAndLimit() {
1670
		$this->Model = new TestModel5();
1671
		$this->Model->schema();
1672
		$this->_buildRelatedModels($this->Model);
1673
 
1674
		$backup = $this->Model->hasMany['TestModel6'];
1675
 
1676
		$this->Model->hasMany['TestModel6']['offset'] = 2;
1677
		$this->Model->hasMany['TestModel6']['limit'] = 5;
1678
 
1679
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1680
		$queryData = array();
1681
 
1682
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1683
 
1684
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1685
 
1686
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1687
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1688
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1689
		$this->assertRegExp('/\s+LIMIT 2,\s*5\s*$/', $result);
1690
 
1691
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1692
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1693
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1694
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1695
 
1696
		$this->Model->hasMany['TestModel6'] = $backup;
1697
	}
1698
 
1699
/**
1700
 * testGenerateAssociationQueryHasManyWithPageAndLimit method
1701
 *
1702
 * @return void
1703
 */
1704
	public function testGenerateAssociationQueryHasManyWithPageAndLimit() {
1705
		$this->Model = new TestModel5();
1706
		$this->Model->schema();
1707
		$this->_buildRelatedModels($this->Model);
1708
 
1709
		$backup = $this->Model->hasMany['TestModel6'];
1710
 
1711
		$this->Model->hasMany['TestModel6']['page'] = 2;
1712
		$this->Model->hasMany['TestModel6']['limit'] = 5;
1713
 
1714
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1715
 
1716
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1717
 
1718
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1719
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1720
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1721
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1722
		$this->assertRegExp('/\s+LIMIT 5,\s*5\s*$/', $result);
1723
 
1724
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1725
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
1726
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1727
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1728
 
1729
		$this->Model->hasMany['TestModel6'] = $backup;
1730
	}
1731
 
1732
/**
1733
 * testGenerateAssociationQueryHasManyWithFields method
1734
 *
1735
 * @return void
1736
 */
1737
	public function testGenerateAssociationQueryHasManyWithFields() {
1738
		$this->Model = new TestModel5();
1739
		$this->Model->schema();
1740
		$this->_buildRelatedModels($this->Model);
1741
 
1742
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1743
		$queryData = array('fields' => array('`TestModel5`.`name`'));
1744
 
1745
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1746
 
1747
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1748
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1749
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1750
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1751
 
1752
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1753
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`id`\s+/', $result);
1754
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1755
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1756
 
1757
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1758
		$queryData = array('fields' => array('`TestModel5`.`id`, `TestModel5`.`name`'));
1759
 
1760
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1761
 
1762
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1763
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1764
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1765
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1766
 
1767
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1768
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1769
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1770
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1771
 
1772
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1773
		$queryData = array('fields' => array('`TestModel5`.`name`', '`TestModel5`.`created`'));
1774
 
1775
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1776
 
1777
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1778
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
1779
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1780
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1781
 
1782
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1783
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`id`\s+/', $result);
1784
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1785
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1786
 
1787
		$this->Model->hasMany['TestModel6']['fields'] = array('name');
1788
 
1789
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1790
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1791
 
1792
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1793
 
1794
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1795
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
1796
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1797
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1798
 
1799
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1800
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1801
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1802
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1803
 
1804
		unset($this->Model->hasMany['TestModel6']['fields']);
1805
 
1806
		$this->Model->hasMany['TestModel6']['fields'] = array('id', 'name');
1807
 
1808
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1809
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1810
 
1811
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1812
 
1813
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1814
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
1815
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1816
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1817
 
1818
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1819
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1820
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1821
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1822
 
1823
		unset($this->Model->hasMany['TestModel6']['fields']);
1824
 
1825
		$this->Model->hasMany['TestModel6']['fields'] = array('test_model5_id', 'name');
1826
 
1827
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1828
		$queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
1829
 
1830
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1831
 
1832
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1833
		$this->assertRegExp('/^SELECT\s+`TestModel6`\.`test_model5_id`, `TestModel6`\.`name`\s+/', $result);
1834
		$this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
1835
		$this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
1836
 
1837
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1838
		$this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
1839
		$this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
1840
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1841
 
1842
		unset($this->Model->hasMany['TestModel6']['fields']);
1843
	}
1844
 
1845
/**
1846
 * test generateAssociationQuery with a hasMany and an aggregate function.
1847
 *
1848
 * @return void
1849
 */
1850
	public function testGenerateAssociationQueryHasManyAndAggregateFunction() {
1851
		$this->Model = new TestModel5();
1852
		$this->Model->schema();
1853
		$this->_buildRelatedModels($this->Model);
1854
 
1855
		$binding = array('type' => 'hasMany', 'model' => 'TestModel6');
1856
		$queryData = array('fields' => array('MIN(`TestModel5`.`test_model4_id`)'));
1857
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1858
		$this->Model->recursive = 0;
1859
 
1860
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1861
		$this->assertRegExp('/^SELECT\s+MIN\(`TestModel5`\.`test_model4_id`\)\s+FROM/', $result);
1862
	}
1863
 
1864
/**
1865
 * testGenerateAssociationQueryHasAndBelongsToMany method
1866
 *
1867
 * @return void
1868
 */
1869
	public function testGenerateAssociationQueryHasAndBelongsToMany() {
1870
		$this->Model = new TestModel4();
1871
		$this->Model->schema();
1872
		$this->_buildRelatedModels($this->Model);
1873
 
1874
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1875
		$queryData = array();
1876
 
1877
		$params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1878
 
1879
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1880
		$assocTable = $this->Dbo->fullTableName($this->Model->TestModel4TestModel7, true, true);
1881
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1882
		$this->assertRegExp('/\s+FROM\s+\S+`test_model7` AS `TestModel7`\s+JOIN\s+' . $assocTable . '/', $result);
1883
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+AND/', $result);
1884
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)/', $result);
1885
		$this->assertRegExp('/WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
1886
 
1887
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1888
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1889
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE/', $result);
1890
		$this->assertRegExp('/\s+WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
1891
	}
1892
 
1893
/**
1894
 * testGenerateAssociationQueryHasAndBelongsToManyWithConditions method
1895
 *
1896
 * @return void
1897
 */
1898
	public function testGenerateAssociationQueryHasAndBelongsToManyWithConditions() {
1899
		$this->Model = new TestModel4();
1900
		$this->Model->schema();
1901
		$this->_buildRelatedModels($this->Model);
1902
 
1903
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1904
		$queryData = array('conditions' => array('TestModel4.name !=' => 'mariano'));
1905
 
1906
		$params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1907
 
1908
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1909
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1910
		$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);
1911
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
1912
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
1913
 
1914
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1915
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1916
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?`TestModel4`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
1917
	}
1918
 
1919
/**
1920
 * testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit method
1921
 *
1922
 * @return void
1923
 */
1924
	public function testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit() {
1925
		$this->Model = new TestModel4();
1926
		$this->Model->schema();
1927
		$this->_buildRelatedModels($this->Model);
1928
 
1929
		$backup = $this->Model->hasAndBelongsToMany['TestModel7'];
1930
 
1931
		$this->Model->hasAndBelongsToMany['TestModel7']['offset'] = 2;
1932
		$this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
1933
 
1934
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1935
		$queryData = array();
1936
 
1937
		$params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
1938
 
1939
		$result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external']);
1940
		$this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
1941
		$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);
1942
		$this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+/', $result);
1943
		$this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
1944
		$this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 2,\s*5\s*$/', $result);
1945
 
1946
		$result = $this->Dbo->buildAssociationQuery($this->Model, $queryData);
1947
		$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
1948
		$this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
1949
 
1950
		$this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
1951
	}
1952
 
1953
/**
1954
 * testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit method
1955
 *
1956
 * @return void
1957
 */
1958
	public function testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit() {
1959
		$this->Model = new TestModel4();
1960
		$this->Model->schema();
1961
		$this->_buildRelatedModels($this->Model);
1962
 
1963
		$backup = $this->Model->hasAndBelongsToMany['TestModel7'];
1964
 
1965
		$this->Model->hasAndBelongsToMany['TestModel7']['page'] = 2;
1966
		$this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
1967
 
1968
		$binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
1969
		$queryData = array();
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']);
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->buildAssociationQuery($this->Model, $queryData);
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
		$date = date('Y-m-d H:i');
2030
		$result = $this->Dbo->conditions("(Post.created < '" . $date . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
2031
		$expected = " WHERE (`Post`.`created` < '" . $date . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
2032
		$this->assertEquals($expected, $result);
2033
 
2034
		$result = $this->Dbo->conditions("score BETWEEN 90.1 AND 95.7");
2035
		$expected = " WHERE score BETWEEN 90.1 AND 95.7";
2036
		$this->assertEquals($expected, $result);
2037
 
2038
		$result = $this->Dbo->conditions(array('score' => array(2 => 1, 2, 10)));
2039
		$expected = " WHERE `score` IN (1, 2, 10)";
2040
		$this->assertEquals($expected, $result);
2041
 
2042
		$result = $this->Dbo->conditions("Aro.rght = Aro.lft + 1.1");
2043
		$expected = " WHERE `Aro`.`rght` = `Aro`.`lft` + 1.1";
2044
		$this->assertEquals($expected, $result);
2045
 
2046
		$date = date('Y-m-d H:i:s');
2047
		$result = $this->Dbo->conditions("(Post.created < '" . $date . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
2048
		$expected = " WHERE (`Post`.`created` < '" . $date . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
2049
		$this->assertEquals($expected, $result);
2050
 
2051
		$result = $this->Dbo->conditions('Sportstaette.sportstaette LIKE "%ru%" AND Sportstaette.sportstaettenart_id = 2');
2052
		$expected = ' WHERE `Sportstaette`.`sportstaette` LIKE "%ru%" AND `Sportstaette`.`sportstaettenart_id` = 2';
2053
		$this->assertRegExp('/\s*WHERE\s+`Sportstaette`\.`sportstaette`\s+LIKE\s+"%ru%"\s+AND\s+`Sports/', $result);
2054
		$this->assertEquals($expected, $result);
2055
 
2056
		$result = $this->Dbo->conditions('Sportstaette.sportstaettenart_id = 2 AND Sportstaette.sportstaette LIKE "%ru%"');
2057
		$expected = ' WHERE `Sportstaette`.`sportstaettenart_id` = 2 AND `Sportstaette`.`sportstaette` LIKE "%ru%"';
2058
		$this->assertEquals($expected, $result);
2059
 
2060
		$result = $this->Dbo->conditions('SUM(Post.comments_count) > 500 AND NOT Post.title IS NULL AND NOT Post.extended_title IS NULL');
2061
		$expected = ' WHERE SUM(`Post`.`comments_count`) > 500 AND NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL';
2062
		$this->assertEquals($expected, $result);
2063
 
2064
		$result = $this->Dbo->conditions('NOT Post.title IS NULL AND NOT Post.extended_title IS NULL AND SUM(Post.comments_count) > 500');
2065
		$expected = ' WHERE NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL AND SUM(`Post`.`comments_count`) > 500';
2066
		$this->assertEquals($expected, $result);
2067
 
2068
		$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');
2069
		$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';
2070
		$this->assertEquals($expected, $result);
2071
 
2072
		$result = $this->Dbo->conditions('NOT Post.title_extended IS NULL AND NOT Post.title IS NULL AND Post.title_extended != Post.title');
2073
		$expected = ' WHERE NOT `Post`.`title_extended` IS NULL AND NOT `Post`.`title` IS NULL AND `Post`.`title_extended` != `Post`.`title`';
2074
		$this->assertEquals($expected, $result);
2075
 
2076
		$result = $this->Dbo->conditions("Comment.id = 'a'");
2077
		$expected = " WHERE `Comment`.`id` = 'a'";
2078
		$this->assertEquals($expected, $result);
2079
 
2080
		$result = $this->Dbo->conditions("lower(Article.title) LIKE 'a%'");
2081
		$expected = " WHERE lower(`Article`.`title`) LIKE 'a%'";
2082
		$this->assertEquals($expected, $result);
2083
 
2084
		$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))');
2085
		$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))';
2086
		$this->assertEquals($expected, $result);
2087
 
2088
		$result = $this->Dbo->conditions('DATEDIFF(NOW(),Article.published) < 1 && Article.live=1');
2089
		$expected = " WHERE DATEDIFF(NOW(),`Article`.`published`) < 1 && `Article`.`live`=1";
2090
		$this->assertEquals($expected, $result);
2091
 
2092
		$result = $this->Dbo->conditions('file = "index.html"');
2093
		$expected = ' WHERE file = "index.html"';
2094
		$this->assertEquals($expected, $result);
2095
 
2096
		$result = $this->Dbo->conditions("file = 'index.html'");
2097
		$expected = " WHERE file = 'index.html'";
2098
		$this->assertEquals($expected, $result);
2099
 
2100
		$letter = $letter = 'd.a';
2101
		$conditions = array('Company.name like ' => $letter . '%');
2102
		$result = $this->Dbo->conditions($conditions);
2103
		$expected = " WHERE `Company`.`name` like 'd.a%'";
2104
		$this->assertEquals($expected, $result);
2105
 
2106
		$conditions = array('Artist.name' => 'JUDY and MARY');
2107
		$result = $this->Dbo->conditions($conditions);
2108
		$expected = " WHERE `Artist`.`name` = 'JUDY and MARY'";
2109
		$this->assertEquals($expected, $result);
2110
 
2111
		$conditions = array('Artist.name' => 'JUDY AND MARY');
2112
		$result = $this->Dbo->conditions($conditions);
2113
		$expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
2114
		$this->assertEquals($expected, $result);
2115
 
2116
		$conditions = array('Company.name similar to ' => 'a word');
2117
		$result = $this->Dbo->conditions($conditions);
2118
		$expected = " WHERE `Company`.`name` similar to 'a word'";
2119
		$this->assertEquals($expected, $result);
2120
	}
2121
 
2122
/**
2123
 * testQuotesInStringConditions method
2124
 *
2125
 * @return void
2126
 */
2127
	public function testQuotesInStringConditions() {
2128
		$result = $this->Dbo->conditions('Member.email = \'mariano@cricava.com\'');
2129
		$expected = ' WHERE `Member`.`email` = \'mariano@cricava.com\'';
2130
		$this->assertEquals($expected, $result);
2131
 
2132
		$result = $this->Dbo->conditions('Member.email = "mariano@cricava.com"');
2133
		$expected = ' WHERE `Member`.`email` = "mariano@cricava.com"';
2134
		$this->assertEquals($expected, $result);
2135
 
2136
		$result = $this->Dbo->conditions('Member.email = \'mariano@cricava.com\' AND Member.user LIKE \'mariano.iglesias%\'');
2137
		$expected = ' WHERE `Member`.`email` = \'mariano@cricava.com\' AND `Member`.`user` LIKE \'mariano.iglesias%\'';
2138
		$this->assertEquals($expected, $result);
2139
 
2140
		$result = $this->Dbo->conditions('Member.email = "mariano@cricava.com" AND Member.user LIKE "mariano.iglesias%"');
2141
		$expected = ' WHERE `Member`.`email` = "mariano@cricava.com" AND `Member`.`user` LIKE "mariano.iglesias%"';
2142
		$this->assertEquals($expected, $result);
2143
	}
2144
 
2145
/**
2146
 * test that - in conditions and field names works
2147
 *
2148
 * @return void
2149
 */
2150
	public function testHypenInStringConditionsAndFieldNames() {
2151
		$result = $this->Dbo->conditions('I18n__title_pt-br.content = "test"');
2152
		$this->assertEquals(' WHERE `I18n__title_pt-br`.`content` = "test"', $result);
2153
 
2154
		$result = $this->Dbo->conditions('Model.field=NOW()-3600');
2155
		$this->assertEquals(' WHERE `Model`.`field`=NOW()-3600', $result);
2156
 
2157
		$result = $this->Dbo->conditions('NOW() - Model.created < 7200');
2158
		$this->assertEquals(' WHERE NOW() - `Model`.`created` < 7200', $result);
2159
 
2160
		$result = $this->Dbo->conditions('NOW()-Model.created < 7200');
2161
		$this->assertEquals(' WHERE NOW()-`Model`.`created` < 7200', $result);
2162
	}
2163
 
2164
/**
2165
 * testParenthesisInStringConditions method
2166
 *
2167
 * @return void
2168
 */
2169
	public function testParenthesisInStringConditions() {
2170
		$result = $this->Dbo->conditions('Member.name = \'(lu\'');
2171
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
2172
 
2173
		$result = $this->Dbo->conditions('Member.name = \')lu\'');
2174
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
2175
 
2176
		$result = $this->Dbo->conditions('Member.name = \'va(lu\'');
2177
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
2178
 
2179
		$result = $this->Dbo->conditions('Member.name = \'va)lu\'');
2180
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
2181
 
2182
		$result = $this->Dbo->conditions('Member.name = \'va(lu)\'');
2183
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
2184
 
2185
		$result = $this->Dbo->conditions('Member.name = \'va(lu)e\'');
2186
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
2187
 
2188
		$result = $this->Dbo->conditions('Member.name = \'(mariano)\'');
2189
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
2190
 
2191
		$result = $this->Dbo->conditions('Member.name = \'(mariano)iglesias\'');
2192
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
2193
 
2194
		$result = $this->Dbo->conditions('Member.name = \'(mariano) iglesias\'');
2195
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
2196
 
2197
		$result = $this->Dbo->conditions('Member.name = \'(mariano word) iglesias\'');
2198
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
2199
 
2200
		$result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias)\'');
2201
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
2202
 
2203
		$result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias)\'');
2204
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
2205
 
2206
		$result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias) CakePHP\'');
2207
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
2208
 
2209
		$result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias) CakePHP\'');
2210
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
2211
	}
2212
 
2213
/**
2214
 * testParenthesisInArrayConditions method
2215
 *
2216
 * @return void
2217
 */
2218
	public function testParenthesisInArrayConditions() {
2219
		$result = $this->Dbo->conditions(array('Member.name' => '(lu'));
2220
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
2221
 
2222
		$result = $this->Dbo->conditions(array('Member.name' => ')lu'));
2223
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
2224
 
2225
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu'));
2226
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
2227
 
2228
		$result = $this->Dbo->conditions(array('Member.name' => 'va)lu'));
2229
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
2230
 
2231
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu)'));
2232
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
2233
 
2234
		$result = $this->Dbo->conditions(array('Member.name' => 'va(lu)e'));
2235
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
2236
 
2237
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano)'));
2238
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
2239
 
2240
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano)iglesias'));
2241
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
2242
 
2243
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano) iglesias'));
2244
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
2245
 
2246
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano word) iglesias'));
2247
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
2248
 
2249
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias)'));
2250
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
2251
 
2252
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias)'));
2253
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
2254
 
2255
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias) CakePHP'));
2256
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
2257
 
2258
		$result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias) CakePHP'));
2259
		$this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
2260
	}
2261
 
2262
/**
2263
 * testArrayConditionsParsing method
2264
 *
2265
 * @return void
2266
 */
2267
	public function testArrayConditionsParsing() {
2268
		$this->loadFixtures('Post', 'Author');
2269
		$result = $this->Dbo->conditions(array('Stereo.type' => 'in dash speakers'));
2270
		$this->assertRegExp("/^\s+WHERE\s+`Stereo`.`type`\s+=\s+'in dash speakers'/", $result);
2271
 
2272
		$result = $this->Dbo->conditions(array('Candy.name LIKE' => 'a', 'HardCandy.name LIKE' => 'c'));
2273
		$this->assertRegExp("/^\s+WHERE\s+`Candy`.`name` LIKE\s+'a'\s+AND\s+`HardCandy`.`name`\s+LIKE\s+'c'/", $result);
2274
 
2275
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a', 'Candy.name LIKE' => 'c'));
2276
		$expected = " WHERE `HardCandy`.`name` LIKE 'a' AND `Candy`.`name` LIKE 'c'";
2277
		$this->assertEquals($expected, $result);
2278
 
2279
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a%', 'Candy.name LIKE' => '%c%'));
2280
		$expected = " WHERE `HardCandy`.`name` LIKE 'a%' AND `Candy`.`name` LIKE '%c%'";
2281
		$this->assertEquals($expected, $result);
2282
 
2283
		$result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'to be or%', 'Candy.name LIKE' => '%not to be%'));
2284
		$expected = " WHERE `HardCandy`.`name` LIKE 'to be or%' AND `Candy`.`name` LIKE '%not to be%'";
2285
		$this->assertEquals($expected, $result);
2286
 
2287
		$result = $this->Dbo->conditions(array(
2288
			"Person.name || ' ' || Person.surname ILIKE" => '%mark%'
2289
		));
2290
		$expected = " WHERE `Person`.`name` || ' ' || `Person`.`surname` ILIKE '%mark%'";
2291
		$this->assertEquals($expected, $result);
2292
 
2293
		$result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
2294
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2295
		$this->assertEquals($expected, $result);
2296
 
2297
		$result = $this->Dbo->conditions(array('Post.title' => 1.1));
2298
		$expected = " WHERE `Post`.`title` = 1.1";
2299
		$this->assertEquals($expected, $result);
2300
 
2301
		$result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
2302
		$expected = " WHERE `Post`.`title` = '1.1'";
2303
		$this->assertEquals($expected, $result);
2304
 
2305
		$result = $this->Dbo->conditions(array('SUM(Post.comments_count) >' => '500'));
2306
		$expected = " WHERE SUM(`Post`.`comments_count`) > '500'";
2307
		$this->assertEquals($expected, $result);
2308
 
2309
		$result = $this->Dbo->conditions(array('MAX(Post.rating) >' => '50'));
2310
		$expected = " WHERE MAX(`Post`.`rating`) > '50'";
2311
		$this->assertEquals($expected, $result);
2312
 
2313
		$result = $this->Dbo->conditions(array('lower(Article.title)' => 'secrets'));
2314
		$expected = " WHERE lower(`Article`.`title`) = 'secrets'";
2315
		$this->assertEquals($expected, $result);
2316
 
2317
		$result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
2318
		$expected = " WHERE `title` LIKE '%hello'";
2319
		$this->assertEquals($expected, $result);
2320
 
2321
		$result = $this->Dbo->conditions(array('Post.name' => 'mad(g)ik'));
2322
		$expected = " WHERE `Post`.`name` = 'mad(g)ik'";
2323
		$this->assertEquals($expected, $result);
2324
 
2325
		$result = $this->Dbo->conditions(array('score' => array(1, 2, 10)));
2326
		$expected = " WHERE `score` IN (1, 2, 10)";
2327
		$this->assertEquals($expected, $result);
2328
 
2329
		$result = $this->Dbo->conditions(array('score' => array()));
2330
		$expected = " WHERE `score` IS NULL";
2331
		$this->assertEquals($expected, $result);
2332
 
2333
		$result = $this->Dbo->conditions(array('score !=' => array()));
2334
		$expected = " WHERE `score` IS NOT NULL";
2335
		$this->assertEquals($expected, $result);
2336
 
2337
		$result = $this->Dbo->conditions(array('score !=' => '20'));
2338
		$expected = " WHERE `score` != '20'";
2339
		$this->assertEquals($expected, $result);
2340
 
2341
		$result = $this->Dbo->conditions(array('score >' => '20'));
2342
		$expected = " WHERE `score` > '20'";
2343
		$this->assertEquals($expected, $result);
2344
 
2345
		$result = $this->Dbo->conditions(array('client_id >' => '20'), true, true, new TestModel());
2346
		$expected = " WHERE `client_id` > 20";
2347
		$this->assertEquals($expected, $result);
2348
 
2349
		$result = $this->Dbo->conditions(array('OR' => array(
2350
			array('User.user' => 'mariano'),
2351
			array('User.user' => 'nate')
2352
		)));
2353
 
2354
		$expected = " WHERE ((`User`.`user` = 'mariano') OR (`User`.`user` = 'nate'))";
2355
		$this->assertEquals($expected, $result);
2356
 
2357
		$result = $this->Dbo->conditions(array('or' => array(
2358
			'score BETWEEN ? AND ?' => array('4', '5'), 'rating >' => '20'
2359
		)));
2360
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`rating` > '20'))";
2361
		$this->assertEquals($expected, $result);
2362
 
2363
		$result = $this->Dbo->conditions(array('or' => array(
2364
			'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
2365
		)));
2366
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`score` > '20'))";
2367
		$this->assertEquals($expected, $result);
2368
 
2369
		$result = $this->Dbo->conditions(array('and' => array(
2370
			'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
2371
		)));
2372
		$expected = " WHERE ((`score` BETWEEN '4' AND '5') AND (`score` > '20'))";
2373
		$this->assertEquals($expected, $result);
2374
 
2375
		$result = $this->Dbo->conditions(array(
2376
			'published' => 1, 'or' => array('score >' => '2', array('score >' => '20'))
2377
		));
2378
		$expected = " WHERE `published` = 1 AND ((`score` > '2') OR (`score` > '20'))";
2379
		$this->assertEquals($expected, $result);
2380
 
2381
		$result = $this->Dbo->conditions(array(array('Project.removed' => false)));
2382
		$expected = " WHERE `Project`.`removed` = '0'";
2383
		$this->assertEquals($expected, $result);
2384
 
2385
		$result = $this->Dbo->conditions(array(array('Project.removed' => true)));
2386
		$expected = " WHERE `Project`.`removed` = '1'";
2387
		$this->assertEquals($expected, $result);
2388
 
2389
		$result = $this->Dbo->conditions(array(array('Project.removed' => null)));
2390
		$expected = " WHERE `Project`.`removed` IS NULL";
2391
		$this->assertEquals($expected, $result);
2392
 
2393
		$result = $this->Dbo->conditions(array(array('Project.removed !=' => null)));
2394
		$expected = " WHERE `Project`.`removed` IS NOT NULL";
2395
		$this->assertEquals($expected, $result);
2396
 
2397
		$result = $this->Dbo->conditions(array('(Usergroup.permissions) & 4' => 4));
2398
		$expected = " WHERE (`Usergroup`.`permissions`) & 4 = 4";
2399
		$this->assertEquals($expected, $result);
2400
 
2401
		$result = $this->Dbo->conditions(array('((Usergroup.permissions) & 4)' => 4));
2402
		$expected = " WHERE ((`Usergroup`.`permissions`) & 4) = 4";
2403
		$this->assertEquals($expected, $result);
2404
 
2405
		$result = $this->Dbo->conditions(array('Post.modified >=' => 'DATE_SUB(NOW(), INTERVAL 7 DAY)'));
2406
		$expected = " WHERE `Post`.`modified` >= 'DATE_SUB(NOW(), INTERVAL 7 DAY)'";
2407
		$this->assertEquals($expected, $result);
2408
 
2409
		$result = $this->Dbo->conditions(array('Post.modified >= DATE_SUB(NOW(), INTERVAL 7 DAY)'));
2410
		$expected = " WHERE `Post`.`modified` >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
2411
		$this->assertEquals($expected, $result);
2412
 
2413
		$result = $this->Dbo->conditions(array(
2414
			'NOT' => array('Course.id' => null, 'Course.vet' => 'N', 'level_of_education_id' => array(912, 999)),
2415
			'Enrollment.yearcompleted >' => '0')
2416
		);
2417
		$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);
2418
 
2419
		$result = $this->Dbo->conditions(array('id <>' => '8'));
2420
		$this->assertRegExp('/^\s*WHERE\s+`id`\s+<>\s+\'8\'\s*$/', $result);
2421
 
2422
		$result = $this->Dbo->conditions(array('TestModel.field =' => 'gribe$@()lu'));
2423
		$expected = " WHERE `TestModel`.`field` = 'gribe$@()lu'";
2424
		$this->assertEquals($expected, $result);
2425
 
2426
		$conditions['NOT'] = array('Listing.expiration BETWEEN ? AND ?' => array("1", "100"));
2427
		$conditions[0]['OR'] = array(
2428
			"Listing.title LIKE" => "%term%",
2429
			"Listing.description LIKE" => "%term%"
2430
		);
2431
		$conditions[1]['OR'] = array(
2432
			"Listing.title LIKE" => "%term_2%",
2433
			"Listing.description LIKE" => "%term_2%"
2434
		);
2435
		$result = $this->Dbo->conditions($conditions);
2436
		$expected = " WHERE NOT (`Listing`.`expiration` BETWEEN '1' AND '100') AND" .
2437
		" ((`Listing`.`title` LIKE '%term%') OR (`Listing`.`description` LIKE '%term%')) AND" .
2438
		" ((`Listing`.`title` LIKE '%term_2%') OR (`Listing`.`description` LIKE '%term_2%'))";
2439
		$this->assertEquals($expected, $result);
2440
 
2441
		$result = $this->Dbo->conditions(array('MD5(CONCAT(Reg.email,Reg.id))' => 'blah'));
2442
		$expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) = 'blah'";
2443
		$this->assertEquals($expected, $result);
2444
 
2445
		$result = $this->Dbo->conditions(array(
2446
			'MD5(CONCAT(Reg.email,Reg.id))' => array('blah', 'blahblah')
2447
		));
2448
		$expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) IN ('blah', 'blahblah')";
2449
		$this->assertEquals($expected, $result);
2450
 
2451
		$conditions = array('id' => array(2, 5, 6, 9, 12, 45, 78, 43, 76));
2452
		$result = $this->Dbo->conditions($conditions);
2453
		$expected = " WHERE `id` IN (2, 5, 6, 9, 12, 45, 78, 43, 76)";
2454
		$this->assertEquals($expected, $result);
2455
 
2456
		$conditions = array('`Correction`.`source` collate utf8_bin' => array('kiwi', 'pear'));
2457
		$result = $this->Dbo->conditions($conditions);
2458
		$expected = " WHERE `Correction`.`source` collate utf8_bin IN ('kiwi', 'pear')";
2459
		$this->assertEquals($expected, $result);
2460
 
2461
		$conditions = array('title' => 'user(s)');
2462
		$result = $this->Dbo->conditions($conditions);
2463
		$expected = " WHERE `title` = 'user(s)'";
2464
		$this->assertEquals($expected, $result);
2465
 
2466
		$conditions = array('title' => 'user(s) data');
2467
		$result = $this->Dbo->conditions($conditions);
2468
		$expected = " WHERE `title` = 'user(s) data'";
2469
		$this->assertEquals($expected, $result);
2470
 
2471
		$conditions = array('title' => 'user(s,arg) data');
2472
		$result = $this->Dbo->conditions($conditions);
2473
		$expected = " WHERE `title` = 'user(s,arg) data'";
2474
		$this->assertEquals($expected, $result);
2475
 
2476
		$result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM)'));
2477
		$expected = " WHERE `Book`.`book_name` = 'Java(TM)'";
2478
		$this->assertEquals($expected, $result);
2479
 
2480
		$result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM) '));
2481
		$expected = " WHERE `Book`.`book_name` = 'Java(TM) '";
2482
		$this->assertEquals($expected, $result);
2483
 
2484
		$result = $this->Dbo->conditions(array("Book.id" => 0));
2485
		$expected = " WHERE `Book`.`id` = 0";
2486
		$this->assertEquals($expected, $result);
2487
 
2488
		$result = $this->Dbo->conditions(array("Book.id" => null));
2489
		$expected = " WHERE `Book`.`id` IS NULL";
2490
		$this->assertEquals($expected, $result);
2491
 
2492
		$conditions = array('MysqlModel.id' => '');
2493
		$result = $this->Dbo->conditions($conditions, true, true, $this->model);
2494
		$expected = " WHERE `MysqlModel`.`id` IS NULL";
2495
		$this->assertEquals($expected, $result);
2496
 
2497
		$result = $this->Dbo->conditions(array('Listing.beds >=' => 0));
2498
		$expected = " WHERE `Listing`.`beds` >= 0";
2499
		$this->assertEquals($expected, $result);
2500
 
2501
		$result = $this->Dbo->conditions(array(
2502
			'ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN ? AND ?' => array(65, 90)
2503
		));
2504
		$expected = ' WHERE ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN 65 AND 90';
2505
		$this->assertEquals($expected, $result);
2506
 
2507
		$result = $this->Dbo->conditions(array('or' => array(
2508
			'? BETWEEN Model.field1 AND Model.field2' => '2009-03-04'
2509
		)));
2510
		$expected = " WHERE '2009-03-04' BETWEEN Model.field1 AND Model.field2";
2511
		$this->assertEquals($expected, $result);
2512
	}
2513
 
2514
/**
2515
 * test conditions() with replacements.
2516
 *
2517
 * @return void
2518
 */
2519
	public function testConditionsWithReplacements() {
2520
		$result = $this->Dbo->conditions(array(
2521
			'score BETWEEN :0 AND :1' => array(90.1, 95.7)
2522
		));
2523
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2524
		$this->assertEquals($expected, $result);
2525
 
2526
		$result = $this->Dbo->conditions(array(
2527
			'score BETWEEN ? AND ?' => array(90.1, 95.7)
2528
		));
2529
		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
2530
		$this->assertEquals($expected, $result);
2531
	}
2532
 
2533
/**
2534
 * Test that array conditions with only one element work.
2535
 *
2536
 * @return void
2537
 */
2538
	public function testArrayConditionsOneElement() {
2539
		$conditions = array('id' => array(1));
2540
		$result = $this->Dbo->conditions($conditions);
2541
		$expected = " WHERE id = (1)";
2542
		$this->assertEquals($expected, $result);
2543
 
2544
		$conditions = array('id NOT' => array(1));
2545
		$result = $this->Dbo->conditions($conditions);
2546
		$expected = " WHERE NOT (id = (1))";
2547
		$this->assertEquals($expected, $result);
2548
	}
2549
 
2550
/**
2551
 * testArrayConditionsParsingComplexKeys method
2552
 *
2553
 * @return void
2554
 */
2555
	public function testArrayConditionsParsingComplexKeys() {
2556
		$result = $this->Dbo->conditions(array(
2557
			'CAST(Book.created AS DATE)' => '2008-08-02'
2558
		));
2559
		$expected = " WHERE CAST(`Book`.`created` AS DATE) = '2008-08-02'";
2560
		$this->assertEquals($expected, $result);
2561
 
2562
		$result = $this->Dbo->conditions(array(
2563
			'CAST(Book.created AS DATE) <=' => '2008-08-02'
2564
		));
2565
		$expected = " WHERE CAST(`Book`.`created` AS DATE) <= '2008-08-02'";
2566
		$this->assertEquals($expected, $result);
2567
 
2568
		$result = $this->Dbo->conditions(array(
2569
			'(Stats.clicks * 100) / Stats.views >' => 50
2570
		));
2571
		$expected = " WHERE (`Stats`.`clicks` * 100) / `Stats`.`views` > 50";
2572
		$this->assertEquals($expected, $result);
2573
	}
2574
 
2575
/**
2576
 * testMixedConditionsParsing method
2577
 *
2578
 * @return void
2579
 */
2580
	public function testMixedConditionsParsing() {
2581
		$conditions[] = 'User.first_name = \'Firstname\'';
2582
		$conditions[] = array('User.last_name' => 'Lastname');
2583
		$result = $this->Dbo->conditions($conditions);
2584
		$expected = " WHERE `User`.`first_name` = 'Firstname' AND `User`.`last_name` = 'Lastname'";
2585
		$this->assertEquals($expected, $result);
2586
 
2587
		$conditions = array(
2588
			'Thread.project_id' => 5,
2589
			'Thread.buyer_id' => 14,
2590
			'1=1 GROUP BY Thread.project_id'
2591
		);
2592
		$result = $this->Dbo->conditions($conditions);
2593
		$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);
2594
	}
2595
 
2596
/**
2597
 * testConditionsOptionalArguments method
2598
 *
2599
 * @return void
2600
 */
2601
	public function testConditionsOptionalArguments() {
2602
		$result = $this->Dbo->conditions(array('Member.name' => 'Mariano'), true, false);
2603
		$this->assertRegExp('/^\s*`Member`.`name`\s*=\s*\'Mariano\'\s*$/', $result);
2604
 
2605
		$result = $this->Dbo->conditions(array(), true, false);
2606
		$this->assertRegExp('/^\s*1\s*=\s*1\s*$/', $result);
2607
	}
2608
 
2609
/**
2610
 * testConditionsWithModel
2611
 *
2612
 * @return void
2613
 */
2614
	public function testConditionsWithModel() {
2615
		$this->Model = new Article2();
2616
 
2617
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => 0), true, true, $this->Model);
2618
		$expected = " WHERE `Article2`.`viewed` >= 0";
2619
		$this->assertEquals($expected, $result);
2620
 
2621
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => '0'), true, true, $this->Model);
2622
		$expected = " WHERE `Article2`.`viewed` >= 0";
2623
		$this->assertEquals($expected, $result);
2624
 
2625
		$result = $this->Dbo->conditions(array('Article2.viewed >=' => '1'), true, true, $this->Model);
2626
		$expected = " WHERE `Article2`.`viewed` >= 1";
2627
		$this->assertEquals($expected, $result);
2628
 
2629
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array(0, 10)), true, true, $this->Model);
2630
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
2631
		$this->assertEquals($expected, $result);
2632
 
2633
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('0', '10')), true, true, $this->Model);
2634
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
2635
		$this->assertEquals($expected, $result);
2636
 
2637
		$result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('1', '10')), true, true, $this->Model);
2638
		$expected = " WHERE `Article2`.`rate_sum` BETWEEN 1 AND 10";
2639
		$this->assertEquals($expected, $result);
2640
	}
2641
 
2642
/**
2643
 * testFieldParsing method
2644
 *
2645
 * @return void
2646
 */
2647
	public function testFieldParsing() {
2648
		$this->Model = new TestModel();
2649
		$result = $this->Dbo->fields($this->Model, 'Vendor', "Vendor.id, COUNT(Model.vendor_id) AS `Vendor`.`count`");
2650
		$expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
2651
		$this->assertEquals($expected, $result);
2652
 
2653
		$result = $this->Dbo->fields($this->Model, 'Vendor', "`Vendor`.`id`, COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`");
2654
		$expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
2655
		$this->assertEquals($expected, $result);
2656
 
2657
		$result = $this->Dbo->fields($this->Model, 'Post', "CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name, Node.created");
2658
		$expected = array("CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", "`Node`.`created`");
2659
		$this->assertEquals($expected, $result);
2660
 
2661
		$result = $this->Dbo->fields($this->Model, null, 'round( (3.55441 * fooField), 3 ) AS test');
2662
		$this->assertEquals(array('round( (3.55441 * fooField), 3 ) AS test'), $result);
2663
 
2664
		$result = $this->Dbo->fields($this->Model, null, 'ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating');
2665
		$this->assertEquals(array('ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating'), $result);
2666
 
2667
		$result = $this->Dbo->fields($this->Model, null, 'ROUND(Rating.rate_total / Rating.rate_count,2) AS rating');
2668
		$this->assertEquals(array('ROUND(Rating.rate_total / Rating.rate_count,2) AS rating'), $result);
2669
 
2670
		$result = $this->Dbo->fields($this->Model, 'Post', "Node.created, CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name");
2671
		$expected = array("`Node`.`created`", "CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name");
2672
		$this->assertEquals($expected, $result);
2673
 
2674
		$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");
2675
		$expected = array(
2676
			'2.2', 'COUNT(*)', 'SUM(`Something`.`else`) as sum', '`Node`.`created`',
2677
			"CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", '`Post`.`title`', '`Post`.`1`', '1.1'
2678
		);
2679
		$this->assertEquals($expected, $result);
2680
 
2681
		$result = $this->Dbo->fields($this->Model, null, "(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
2682
		$expected = array("(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
2683
		$this->assertEquals($expected, $result);
2684
 
2685
		$result = $this->Dbo->fields($this->Model, 'Post');
2686
		$expected = array(
2687
			'`Post`.`id`', '`Post`.`client_id`', '`Post`.`name`', '`Post`.`login`',
2688
			'`Post`.`passwd`', '`Post`.`addr_1`', '`Post`.`addr_2`', '`Post`.`zip_code`',
2689
			'`Post`.`city`', '`Post`.`country`', '`Post`.`phone`', '`Post`.`fax`',
2690
			'`Post`.`url`', '`Post`.`email`', '`Post`.`comments`', '`Post`.`last_login`',
2691
			'`Post`.`created`', '`Post`.`updated`'
2692
		);
2693
		$this->assertEquals($expected, $result);
2694
 
2695
		$result = $this->Dbo->fields($this->Model, 'Other');
2696
		$expected = array(
2697
			'`Other`.`id`', '`Other`.`client_id`', '`Other`.`name`', '`Other`.`login`',
2698
			'`Other`.`passwd`', '`Other`.`addr_1`', '`Other`.`addr_2`', '`Other`.`zip_code`',
2699
			'`Other`.`city`', '`Other`.`country`', '`Other`.`phone`', '`Other`.`fax`',
2700
			'`Other`.`url`', '`Other`.`email`', '`Other`.`comments`', '`Other`.`last_login`',
2701
			'`Other`.`created`', '`Other`.`updated`'
2702
		);
2703
		$this->assertEquals($expected, $result);
2704
 
2705
		$result = $this->Dbo->fields($this->Model, null, array(), false);
2706
		$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');
2707
		$this->assertEquals($expected, $result);
2708
 
2709
		$result = $this->Dbo->fields($this->Model, null, 'COUNT(*)');
2710
		$expected = array('COUNT(*)');
2711
		$this->assertEquals($expected, $result);
2712
 
2713
		$result = $this->Dbo->fields($this->Model, null, 'SUM(Thread.unread_buyer) AS ' . $this->Dbo->name('sum_unread_buyer'));
2714
		$expected = array('SUM(`Thread`.`unread_buyer`) AS `sum_unread_buyer`');
2715
		$this->assertEquals($expected, $result);
2716
 
2717
		$result = $this->Dbo->fields($this->Model, null, 'name, count(*)');
2718
		$expected = array('`TestModel`.`name`', 'count(*)');
2719
		$this->assertEquals($expected, $result);
2720
 
2721
		$result = $this->Dbo->fields($this->Model, null, 'count(*), name');
2722
		$expected = array('count(*)', '`TestModel`.`name`');
2723
		$this->assertEquals($expected, $result);
2724
 
2725
		$result = $this->Dbo->fields(
2726
			$this->Model, null, 'field1, field2, field3, count(*), name'
2727
		);
2728
		$expected = array(
2729
			'`TestModel`.`field1`', '`TestModel`.`field2`',
2730
			'`TestModel`.`field3`', 'count(*)', '`TestModel`.`name`'
2731
		);
2732
		$this->assertEquals($expected, $result);
2733
 
2734
		$result = $this->Dbo->fields($this->Model, null, array('dayofyear(now())'));
2735
		$expected = array('dayofyear(now())');
2736
		$this->assertEquals($expected, $result);
2737
 
2738
		$result = $this->Dbo->fields($this->Model, null, array('MAX(Model.field) As Max'));
2739
		$expected = array('MAX(`Model`.`field`) As Max');
2740
		$this->assertEquals($expected, $result);
2741
 
2742
		$result = $this->Dbo->fields($this->Model, null, array('Model.field AS AnotherName'));
2743
		$expected = array('`Model`.`field` AS `AnotherName`');
2744
		$this->assertEquals($expected, $result);
2745
 
2746
		$result = $this->Dbo->fields($this->Model, null, array('field AS AnotherName'));
2747
		$expected = array('`field` AS `AnotherName`');
2748
		$this->assertEquals($expected, $result);
2749
 
2750
		$result = $this->Dbo->fields($this->Model, null, array(
2751
			'TestModel.field AS AnotherName'
2752
		));
2753
		$expected = array('`TestModel`.`field` AS `AnotherName`');
2754
		$this->assertEquals($expected, $result);
2755
 
2756
		$result = $this->Dbo->fields($this->Model, 'Foo', array(
2757
			'id', 'title', '(user_count + discussion_count + post_count) AS score'
2758
		));
2759
		$expected = array(
2760
			'`Foo`.`id`',
2761
			'`Foo`.`title`',
2762
			'(user_count + discussion_count + post_count) AS score'
2763
		);
2764
		$this->assertEquals($expected, $result);
2765
	}
2766
 
2767
/**
2768
 * test that fields() will accept objects made from DboSource::expression
2769
 *
2770
 * @return void
2771
 */
2772
	public function testFieldsWithExpression() {
2773
		$this->Model = new TestModel;
2774
		$expression = $this->Dbo->expression("CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col");
2775
		$result = $this->Dbo->fields($this->Model, null, array("id", $expression));
2776
		$expected = array(
2777
			'`TestModel`.`id`',
2778
			"CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col"
2779
		);
2780
		$this->assertEquals($expected, $result);
2781
	}
2782
 
2783
/**
2784
 * testRenderStatement method
2785
 *
2786
 * @return void
2787
 */
2788
	public function testRenderStatement() {
2789
		$result = $this->Dbo->renderStatement('select', array(
2790
			'fields' => 'id', 'table' => 'table', 'conditions' => 'WHERE 1=1',
2791
			'alias' => '', 'joins' => '', 'order' => '', 'limit' => '', 'group' => ''
2792
		));
2793
		$this->assertRegExp('/^\s*SELECT\s+id\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
2794
 
2795
		$result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
2796
		$this->assertRegExp('/^\s*UPDATE\s+table\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
2797
 
2798
		$result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
2799
		$this->assertRegExp('/^\s*UPDATE\s+table\s+AS\s+alias\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
2800
 
2801
		$result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
2802
		$this->assertRegExp('/^\s*DELETE\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
2803
 
2804
		$result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
2805
		$this->assertRegExp('/^\s*DELETE\s+alias\s+FROM\s+table\s+AS\s+alias\s+WHERE\s+1=1\s*$/', $result);
2806
	}
2807
 
2808
/**
2809
 * testSchema method
2810
 *
2811
 * @return void
2812
 */
2813
	public function testSchema() {
2814
		$Schema = new CakeSchema();
2815
		$Schema->tables = array('table' => array(), 'anotherTable' => array());
2816
 
2817
		$result = $this->Dbo->dropSchema($Schema, 'non_existing');
2818
		$this->assertTrue(empty($result));
2819
 
2820
		$result = $this->Dbo->dropSchema($Schema, 'table');
2821
		$this->assertRegExp('/^\s*DROP TABLE IF EXISTS\s+' . $this->Dbo->fullTableName('table') . ';\s*$/s', $result);
2822
	}
2823
 
2824
/**
2825
 * testDropSchemaNoSchema method
2826
 *
2827
 * @expectedException PHPUnit_Framework_Error
2828
 * @return void
2829
 */
2830
	public function testDropSchemaNoSchema() {
2831
		$this->Dbo->dropSchema(null);
2832
	}
2833
 
2834
/**
2835
 * testOrderParsing method
2836
 *
2837
 * @return void
2838
 */
2839
	public function testOrderParsing() {
2840
		$result = $this->Dbo->order("ADDTIME(Event.time_begin, '-06:00:00') ASC");
2841
		$expected = " ORDER BY ADDTIME(`Event`.`time_begin`, '-06:00:00') ASC";
2842
		$this->assertEquals($expected, $result);
2843
 
2844
		$result = $this->Dbo->order("title, id");
2845
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2846
 
2847
		$result = $this->Dbo->order("title desc, id desc");
2848
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
2849
 
2850
		$result = $this->Dbo->order(array("title desc, id desc"));
2851
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
2852
 
2853
		$result = $this->Dbo->order(array("title", "id"));
2854
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2855
 
2856
		$result = $this->Dbo->order(array(array('title'), array('id')));
2857
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
2858
 
2859
		$result = $this->Dbo->order(array("Post.title" => 'asc', "Post.id" => 'desc'));
2860
		$this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
2861
 
2862
		$result = $this->Dbo->order(array(array("Post.title" => 'asc', "Post.id" => 'desc')));
2863
		$this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
2864
 
2865
		$result = $this->Dbo->order(array("title"));
2866
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
2867
 
2868
		$result = $this->Dbo->order(array(array("title")));
2869
		$this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
2870
 
2871
		$result = $this->Dbo->order("Dealer.id = 7 desc, Dealer.id = 3 desc, Dealer.title asc");
2872
		$expected = " ORDER BY `Dealer`.`id` = 7 desc, `Dealer`.`id` = 3 desc, `Dealer`.`title` asc";
2873
		$this->assertEquals($expected, $result);
2874
 
2875
		$result = $this->Dbo->order(array("Page.name" => "='test' DESC"));
2876
		$this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*='test'\s+DESC\s*$/", $result);
2877
 
2878
		$result = $this->Dbo->order("Page.name = 'view' DESC");
2879
		$this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*=\s*'view'\s+DESC\s*$/", $result);
2880
 
2881
		$result = $this->Dbo->order("(Post.views)");
2882
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\s+ASC\s*$/", $result);
2883
 
2884
		$result = $this->Dbo->order("(Post.views)*Post.views");
2885
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\*`Post`\.`views`\s+ASC\s*$/", $result);
2886
 
2887
		$result = $this->Dbo->order("(Post.views) * Post.views");
2888
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\) \* `Post`\.`views`\s+ASC\s*$/", $result);
2889
 
2890
		$result = $this->Dbo->order("(Model.field1 + Model.field2) * Model.field3");
2891
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field1` \+ `Model`\.`field2`\) \* `Model`\.`field3`\s+ASC\s*$/", $result);
2892
 
2893
		$result = $this->Dbo->order("Model.name+0 ASC");
2894
		$this->assertRegExp("/^\s*ORDER BY\s+`Model`\.`name`\+0\s+ASC\s*$/", $result);
2895
 
2896
		$result = $this->Dbo->order("Anuncio.destaque & 2 DESC");
2897
		$expected = ' ORDER BY `Anuncio`.`destaque` & 2 DESC';
2898
		$this->assertEquals($expected, $result);
2899
 
2900
		$result = $this->Dbo->order("3963.191 * id");
2901
		$expected = ' ORDER BY 3963.191 * id ASC';
2902
		$this->assertEquals($expected, $result);
2903
 
2904
		$result = $this->Dbo->order(array('Property.sale_price IS NULL'));
2905
		$expected = ' ORDER BY `Property`.`sale_price` IS NULL ASC';
2906
		$this->assertEquals($expected, $result);
2907
	}
2908
 
2909
/**
2910
 * testComplexSortExpression method
2911
 *
2912
 * @return void
2913
 */
2914
	public function testComplexSortExpression() {
2915
		$result = $this->Dbo->order(array('(Model.field > 100) DESC', 'Model.field ASC'));
2916
		$this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field`\s+>\s+100\)\s+DESC,\s+`Model`\.`field`\s+ASC\s*$/", $result);
2917
	}
2918
 
2919
/**
2920
 * testCalculations method
2921
 *
2922
 * @return void
2923
 */
2924
	public function testCalculations() {
2925
		$this->Model = new TestModel();
2926
		$result = $this->Dbo->calculate($this->Model, 'count');
2927
		$this->assertEquals('COUNT(*) AS `count`', $result);
2928
 
2929
		$result = $this->Dbo->calculate($this->Model, 'count', array('id'));
2930
		$this->assertEquals('COUNT(`id`) AS `count`', $result);
2931
 
2932
		$result = $this->Dbo->calculate(
2933
			$this->Model,
2934
			'count',
2935
			array($this->Dbo->expression('DISTINCT id'))
2936
		);
2937
		$this->assertEquals('COUNT(DISTINCT id) AS `count`', $result);
2938
 
2939
		$result = $this->Dbo->calculate($this->Model, 'count', array('id', 'id_count'));
2940
		$this->assertEquals('COUNT(`id`) AS `id_count`', $result);
2941
 
2942
		$result = $this->Dbo->calculate($this->Model, 'count', array('Model.id', 'id_count'));
2943
		$this->assertEquals('COUNT(`Model`.`id`) AS `id_count`', $result);
2944
 
2945
		$result = $this->Dbo->calculate($this->Model, 'max', array('id'));
2946
		$this->assertEquals('MAX(`id`) AS `id`', $result);
2947
 
2948
		$result = $this->Dbo->calculate($this->Model, 'max', array('Model.id', 'id'));
2949
		$this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
2950
 
2951
		$result = $this->Dbo->calculate($this->Model, 'max', array('`Model`.`id`', 'id'));
2952
		$this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
2953
 
2954
		$result = $this->Dbo->calculate($this->Model, 'min', array('`Model`.`id`', 'id'));
2955
		$this->assertEquals('MIN(`Model`.`id`) AS `id`', $result);
2956
 
2957
		$result = $this->Dbo->calculate($this->Model, 'min', 'left');
2958
		$this->assertEquals('MIN(`left`) AS `left`', $result);
2959
	}
2960
 
2961
/**
2962
 * testLength method
2963
 *
2964
 * @return void
2965
 */
2966
	public function testLength() {
2967
		$result = $this->Dbo->length('varchar(255)');
2968
		$expected = 255;
2969
		$this->assertSame($expected, $result);
2970
 
2971
		$result = $this->Dbo->length('int(11)');
2972
		$expected = 11;
2973
		$this->assertSame($expected, $result);
2974
 
2975
		$result = $this->Dbo->length('float(5,3)');
2976
		$expected = '5,3';
2977
		$this->assertSame($expected, $result);
2978
 
2979
		$result = $this->Dbo->length('decimal(5,2)');
2980
		$expected = '5,2';
2981
		$this->assertSame($expected, $result);
2982
 
2983
		$result = $this->Dbo->length("enum('test','me','now')");
2984
		$expected = 4;
2985
		$this->assertSame($expected, $result);
2986
 
2987
		$result = $this->Dbo->length("set('a','b','cd')");
2988
		$expected = 2;
2989
		$this->assertSame($expected, $result);
2990
 
2991
		$result = $this->Dbo->length(false);
2992
		$this->assertTrue($result === null);
2993
 
2994
		$result = $this->Dbo->length('datetime');
2995
		$expected = null;
2996
		$this->assertSame($expected, $result);
2997
 
2998
		$result = $this->Dbo->length('text');
2999
		$expected = null;
3000
		$this->assertSame($expected, $result);
3001
	}
3002
 
3003
/**
3004
 * testBuildIndex method
3005
 *
3006
 * @return void
3007
 */
3008
	public function testBuildIndex() {
3009
		$data = array(
3010
			'PRIMARY' => array('column' => 'id')
3011
		);
3012
		$result = $this->Dbo->buildIndex($data);
3013
		$expected = array('PRIMARY KEY  (`id`)');
3014
		$this->assertSame($expected, $result);
3015
 
3016
		$data = array(
3017
			'MyIndex' => array('column' => 'id', 'unique' => true)
3018
		);
3019
		$result = $this->Dbo->buildIndex($data);
3020
		$expected = array('UNIQUE KEY `MyIndex` (`id`)');
3021
		$this->assertEquals($expected, $result);
3022
 
3023
		$data = array(
3024
			'MyIndex' => array('column' => array('id', 'name'), 'unique' => true)
3025
		);
3026
		$result = $this->Dbo->buildIndex($data);
3027
		$expected = array('UNIQUE KEY `MyIndex` (`id`, `name`)');
3028
		$this->assertEquals($expected, $result);
3029
 
3030
		$data = array(
3031
			'MyFtIndex' => array('column' => array('name', 'description'), 'type' => 'fulltext')
3032
		);
3033
		$result = $this->Dbo->buildIndex($data);
3034
		$expected = array('FULLTEXT KEY `MyFtIndex` (`name`, `description`)');
3035
		$this->assertEquals($expected, $result);
3036
 
3037
		$data = array(
3038
			'MyTextIndex' => array('column' => 'text_field', 'length' => array('text_field' => 20))
3039
		);
3040
		$result = $this->Dbo->buildIndex($data);
3041
		$expected = array('KEY `MyTextIndex` (`text_field`(20))');
3042
		$this->assertEquals($expected, $result);
3043
 
3044
		$data = array(
3045
			'MyMultiTextIndex' => array('column' => array('text_field1', 'text_field2'), 'length' => array('text_field1' => 20, 'text_field2' => 20))
3046
		);
3047
		$result = $this->Dbo->buildIndex($data);
3048
		$expected = array('KEY `MyMultiTextIndex` (`text_field1`(20), `text_field2`(20))');
3049
		$this->assertEquals($expected, $result);
3050
	}
3051
 
3052
/**
3053
 * testBuildColumn method
3054
 *
3055
 * @return void
3056
 */
3057
	public function testBuildColumn2() {
3058
		$data = array(
3059
			'name' => 'testName',
3060
			'type' => 'string',
3061
			'length' => 255,
3062
			'default',
3063
			'null' => true,
3064
			'key'
3065
		);
3066
		$result = $this->Dbo->buildColumn($data);
3067
		$expected = '`testName` varchar(255) DEFAULT NULL';
3068
		$this->assertEquals($expected, $result);
3069
 
3070
		$data = array(
3071
			'name' => 'int_field',
3072
			'type' => 'integer',
3073
			'default' => '',
3074
			'null' => false,
3075
		);
3076
		$restore = $this->Dbo->columns;
3077
 
3078
		$this->Dbo->columns = array('integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), );
3079
		$result = $this->Dbo->buildColumn($data);
3080
		$expected = '`int_field` int(11) NOT NULL';
3081
		$this->assertEquals($expected, $result);
3082
 
3083
		$this->Dbo->fieldParameters['param'] = array(
3084
			'value' => 'COLLATE',
3085
			'quote' => false,
3086
			'join' => ' ',
3087
			'column' => 'Collate',
3088
			'position' => 'beforeDefault',
3089
			'options' => array('GOOD', 'OK')
3090
		);
3091
		$data = array(
3092
			'name' => 'int_field',
3093
			'type' => 'integer',
3094
			'default' => '',
3095
			'null' => false,
3096
			'param' => 'BAD'
3097
		);
3098
		$result = $this->Dbo->buildColumn($data);
3099
		$expected = '`int_field` int(11) NOT NULL';
3100
		$this->assertEquals($expected, $result);
3101
 
3102
		$data = array(
3103
			'name' => 'int_field',
3104
			'type' => 'integer',
3105
			'default' => '',
3106
			'null' => false,
3107
			'param' => 'GOOD'
3108
		);
3109
		$result = $this->Dbo->buildColumn($data);
3110
		$expected = '`int_field` int(11) COLLATE GOOD NOT NULL';
3111
		$this->assertEquals($expected, $result);
3112
 
3113
		$this->Dbo->columns = $restore;
3114
 
3115
		$data = array(
3116
			'name' => 'created',
3117
			'type' => 'timestamp',
3118
			'default' => 'current_timestamp',
3119
			'null' => false,
3120
		);
3121
		$result = $this->Dbo->buildColumn($data);
3122
		$expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL';
3123
		$this->assertEquals($expected, $result);
3124
 
3125
		$data = array(
3126
			'name' => 'created',
3127
			'type' => 'timestamp',
3128
			'default' => 'CURRENT_TIMESTAMP',
3129
			'null' => true,
3130
		);
3131
		$result = $this->Dbo->buildColumn($data);
3132
		$expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP';
3133
		$this->assertEquals($expected, $result);
3134
 
3135
		$data = array(
3136
			'name' => 'modified',
3137
			'type' => 'timestamp',
3138
			'null' => true,
3139
		);
3140
		$result = $this->Dbo->buildColumn($data);
3141
		$expected = '`modified` timestamp NULL';
3142
		$this->assertEquals($expected, $result);
3143
 
3144
		$data = array(
3145
			'name' => 'modified',
3146
			'type' => 'timestamp',
3147
			'default' => null,
3148
			'null' => true,
3149
		);
3150
		$result = $this->Dbo->buildColumn($data);
3151
		$expected = '`modified` timestamp NULL';
3152
		$this->assertEquals($expected, $result);
3153
	}
3154
 
3155
/**
3156
 * testBuildColumnBadType method
3157
 *
3158
 * @expectedException PHPUnit_Framework_Error
3159
 * @return void
3160
 */
3161
	public function testBuildColumnBadType() {
3162
		$data = array(
3163
			'name' => 'testName',
3164
			'type' => 'varchar(255)',
3165
			'default',
3166
			'null' => true,
3167
			'key'
3168
		);
3169
		$this->Dbo->buildColumn($data);
3170
	}
3171
 
3172
/**
3173
 * Test `unsigned` field parameter
3174
 *
3175
 * @param array $data Column data
3176
 * @param string $expected Expected sql part
3177
 *
3178
 * @return void
3179
 *
3180
 * @dataProvider buildColumnUnsignedProvider
3181
 */
3182
	public function testBuildColumnUnsigned($data, $expected) {
3183
		$result = $this->Dbo->buildColumn($data);
3184
		$this->assertEquals($expected, $result);
3185
	}
3186
 
3187
/**
3188
 * Data provider testBuildColumnUnsigned method
3189
 *
3190
 * @return array
3191
 */
3192
	public function buildColumnUnsignedProvider() {
3193
		return array(
3194
			//set #0
3195
			array(
3196
				array(
3197
					'name' => 'testName',
3198
					'type' => 'integer',
3199
					'length' => 11,
3200
					'unsigned' => true
3201
				),
3202
				'`testName` int(11) UNSIGNED'
3203
			),
3204
			//set #1
3205
			array(
3206
				array(
3207
					'name' => 'testName',
3208
					'type' => 'biginteger',
3209
					'length' => 20,
3210
					'unsigned' => true
3211
				),
3212
				'`testName` bigint(20) UNSIGNED'
3213
			),
3214
			//set #2
3215
			array(
3216
				array(
3217
					'name' => 'testName',
3218
					'type' => 'float',
3219
					'unsigned' => true
3220
				),
3221
				'`testName` float UNSIGNED'
3222
			),
3223
			//set #3
3224
			array(
3225
				array(
3226
					'name' => 'testName',
3227
					'type' => 'string',
3228
					'length' => 255,
3229
					'unsigned' => true
3230
				),
3231
				'`testName` varchar(255)'
3232
			),
3233
			//set #4
3234
			array(
3235
				array(
3236
					'name' => 'testName',
3237
					'type' => 'date',
3238
					'unsigned' => true
3239
				),
3240
				'`testName` date'
3241
			),
3242
			//set #5
3243
			array(
3244
				array(
3245
					'name' => 'testName',
3246
					'type' => 'date',
3247
					'unsigned' => false
3248
				),
3249
				'`testName` date'
3250
			),
3251
			//set #6
3252
			array(
3253
				array(
3254
					'name' => 'testName',
3255
					'type' => 'integer',
3256
					'length' => 11,
3257
					'unsigned' => false
3258
				),
3259
				'`testName` int(11)'
3260
			),
3261
			//set #7
3262
			array(
3263
				array(
3264
					'name' => 'testName',
3265
					'type' => 'decimal',
3266
					'unsigned' => true
3267
				),
3268
				'`testName` decimal UNSIGNED'
3269
			),
3270
			//set #8
3271
			array(
3272
				array(
3273
					'name' => 'testName',
3274
					'type' => 'decimal',
3275
					'unsigned' => true,
3276
					'default' => 1
3277
				),
3278
				'`testName` decimal UNSIGNED DEFAULT 1'
3279
			)
3280
		);
3281
	}
3282
 
3283
/**
3284
 * Test getting `unsigned` field parameter from DB
3285
 *
3286
 * @return void
3287
 */
3288
	public function testSchemaUnsigned() {
3289
		$this->loadFixtures('Unsigned');
3290
		$Model = ClassRegistry::init('Model');
3291
		$Model->setSource('unsigned');
3292
		$types = $this->Dbo->fieldParameters['unsigned']['types'];
3293
		$schema = $Model->schema();
3294
		foreach ($types as $type) {
3295
			$this->assertArrayHasKey('unsigned', $schema['u' . $type]);
3296
			$this->assertTrue($schema['u' . $type]['unsigned']);
3297
			$this->assertArrayHasKey('unsigned', $schema[$type]);
3298
			$this->assertFalse($schema[$type]['unsigned']);
3299
		}
3300
		$this->assertArrayNotHasKey('unsigned', $schema['string']);
3301
	}
3302
 
3303
/**
3304
 * test hasAny()
3305
 *
3306
 * @return void
3307
 */
3308
	public function testHasAny() {
3309
		$db = $this->Dbo->config['database'];
3310
		$this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute', 'value'));
3311
		$this->Dbo->config['database'] = $db;
3312
 
3313
		$this->Model = $this->getMock('TestModel', array('getDataSource'));
3314
		$this->Model->expects($this->any())
3315
			->method('getDataSource')
3316
			->will($this->returnValue($this->Dbo));
3317
 
3318
		$this->Dbo->expects($this->at(0))->method('value')
3319
			->with('harry')
3320
			->will($this->returnValue("'harry'"));
3321
 
3322
		$modelTable = $this->Dbo->fullTableName($this->Model);
3323
		$this->Dbo->expects($this->at(1))->method('execute')
3324
			->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE `TestModel`.`name` = \'harry\'');
3325
		$this->Dbo->expects($this->at(2))->method('execute')
3326
			->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE 1 = 1');
3327
 
3328
		$this->Dbo->hasAny($this->Model, array('TestModel.name' => 'harry'));
3329
		$this->Dbo->hasAny($this->Model, array());
3330
	}
3331
 
3332
/**
3333
 * test fields generating usable virtual fields to use in query
3334
 *
3335
 * @return void
3336
 */
3337
	public function testVirtualFields() {
3338
		$this->loadFixtures('Article', 'Comment', 'Tag');
3339
		$this->Dbo->virtualFieldSeparator = '__';
3340
		$Article = ClassRegistry::init('Article');
3341
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3342
		$Article->virtualFields = array(
3343
			'this_moment' => 'NOW()',
3344
			'two' => '1 + 1',
3345
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3346
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3347
		);
3348
		$result = $this->Dbo->fields($Article);
3349
		$expected = array(
3350
			'`Article`.`id`',
3351
			'`Article`.`user_id`',
3352
			'`Article`.`title`',
3353
			'`Article`.`body`',
3354
			'`Article`.`published`',
3355
			'`Article`.`created`',
3356
			'`Article`.`updated`',
3357
			'(NOW()) AS  `Article__this_moment`',
3358
			'(1 + 1) AS  `Article__two`',
3359
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3360
		);
3361
 
3362
		$this->assertEquals($expected, $result);
3363
 
3364
		$result = $this->Dbo->fields($Article, null, array('this_moment', 'title'));
3365
		$expected = array(
3366
			'`Article`.`title`',
3367
			'(NOW()) AS  `Article__this_moment`',
3368
		);
3369
		$this->assertEquals($expected, $result);
3370
 
3371
		$result = $this->Dbo->fields($Article, null, array('Article.title', 'Article.this_moment'));
3372
		$expected = array(
3373
			'`Article`.`title`',
3374
			'(NOW()) AS  `Article__this_moment`',
3375
		);
3376
		$this->assertEquals($expected, $result);
3377
 
3378
		$result = $this->Dbo->fields($Article, null, array('Article.this_moment', 'Article.title'));
3379
		$expected = array(
3380
			'`Article`.`title`',
3381
			'(NOW()) AS  `Article__this_moment`',
3382
		);
3383
		$this->assertEquals($expected, $result);
3384
 
3385
		$result = $this->Dbo->fields($Article, null, array('Article.*'));
3386
		$expected = array(
3387
			'`Article`.*',
3388
			'(NOW()) AS  `Article__this_moment`',
3389
			'(1 + 1) AS  `Article__two`',
3390
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3391
		);
3392
		$this->assertEquals($expected, $result);
3393
 
3394
		$result = $this->Dbo->fields($Article, null, array('*'));
3395
		$expected = array(
3396
			'*',
3397
			'(NOW()) AS  `Article__this_moment`',
3398
			'(1 + 1) AS  `Article__two`',
3399
			"(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS  `Article__comment_count`"
3400
		);
3401
		$this->assertEquals($expected, $result);
3402
	}
3403
 
3404
/**
3405
 * test conditions to generate query conditions for virtual fields
3406
 *
3407
 * @return void
3408
 */
3409
	public function testVirtualFieldsInConditions() {
3410
		$Article = ClassRegistry::init('Article');
3411
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3412
 
3413
		$Article->virtualFields = array(
3414
			'this_moment' => 'NOW()',
3415
			'two' => '1 + 1',
3416
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3417
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3418
		);
3419
		$conditions = array('two' => 2);
3420
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3421
		$expected = '(1 + 1) = 2';
3422
		$this->assertEquals($expected, $result);
3423
 
3424
		$conditions = array('this_moment BETWEEN ? AND ?' => array(1, 2));
3425
		$expected = 'NOW() BETWEEN 1 AND 2';
3426
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3427
		$this->assertEquals($expected, $result);
3428
 
3429
		$conditions = array('comment_count >' => 5);
3430
		$expected = "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) > 5";
3431
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3432
		$this->assertEquals($expected, $result);
3433
 
3434
		$conditions = array('NOT' => array('two' => 2));
3435
		$result = $this->Dbo->conditions($conditions, true, false, $Article);
3436
		$expected = 'NOT ((1 + 1) = 2)';
3437
		$this->assertEquals($expected, $result);
3438
	}
3439
 
3440
/**
3441
 * test that virtualFields with complex functions and aliases work.
3442
 *
3443
 * @return void
3444
 */
3445
	public function testConditionsWithComplexVirtualFields() {
3446
		$Article = ClassRegistry::init('Article', 'Comment', 'Tag');
3447
		$Article->virtualFields = array(
3448
			'distance' => 'ACOS(SIN(20 * PI() / 180)
3449
					* SIN(Article.latitude * PI() / 180)
3450
					+ COS(20 * PI() / 180)
3451
					* COS(Article.latitude * PI() / 180)
3452
					* COS((50 - Article.longitude) * PI() / 180)
3453
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3454
		);
3455
		$conditions = array('distance >=' => 20);
3456
		$result = $this->Dbo->conditions($conditions, true, true, $Article);
3457
 
3458
		$this->assertRegExp('/\) >= 20/', $result);
3459
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result);
3460
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result);
3461
	}
3462
 
3463
/**
3464
 * test calculate to generate claculate statements on virtual fields
3465
 *
3466
 * @return void
3467
 */
3468
	public function testVirtualFieldsInCalculate() {
3469
		$Article = ClassRegistry::init('Article');
3470
		$commentsTable = $this->Dbo->fullTableName('comments', false, false);
3471
		$Article->virtualFields = array(
3472
			'this_moment' => 'NOW()',
3473
			'two' => '1 + 1',
3474
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
3475
				' WHERE Article.id = ' . $commentsTable . '.article_id'
3476
		);
3477
 
3478
		$result = $this->Dbo->calculate($Article, 'count', array('this_moment'));
3479
		$expected = 'COUNT(NOW()) AS `count`';
3480
		$this->assertEquals($expected, $result);
3481
 
3482
		$result = $this->Dbo->calculate($Article, 'max', array('comment_count'));
3483
		$expected = "MAX(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `comment_count`";
3484
		$this->assertEquals($expected, $result);
3485
	}
3486
 
3487
/**
3488
 * test reading virtual fields containing newlines when recursive > 0
3489
 *
3490
 * @return void
3491
 */
3492
	public function testReadVirtualFieldsWithNewLines() {
3493
		$Article = new Article();
3494
		$Article->recursive = 1;
3495
		$Article->virtualFields = array(
3496
			'test' => '
3497
			User.id + User.id
3498
			'
3499
		);
3500
		$result = $this->Dbo->fields($Article, null, array());
3501
		$result = $this->Dbo->fields($Article, $Article->alias, $result);
3502
		$this->assertRegExp('/[`\"]User[`\"]\.[`\"]id[`\"] \+ [`\"]User[`\"]\.[`\"]id[`\"]/', $result[7]);
3503
	}
3504
 
3505
/**
3506
 * test group to generate GROUP BY statements on virtual fields
3507
 *
3508
 * @return void
3509
 */
3510
	public function testVirtualFieldsInGroup() {
3511
		$Article = ClassRegistry::init('Article');
3512
		$Article->virtualFields = array(
3513
			'this_year' => 'YEAR(Article.created)'
3514
		);
3515
 
3516
		$result = $this->Dbo->group('this_year', $Article);
3517
 
3518
		$expected = " GROUP BY (YEAR(`Article`.`created`))";
3519
		$this->assertEquals($expected, $result);
3520
	}
3521
 
3522
/**
3523
 * test that virtualFields with complex functions and aliases work.
3524
 *
3525
 * @return void
3526
 */
3527
	public function testFieldsWithComplexVirtualFields() {
3528
		$Article = new Article();
3529
		$Article->virtualFields = array(
3530
			'distance' => 'ACOS(SIN(20 * PI() / 180)
3531
					* SIN(Article.latitude * PI() / 180)
3532
					+ COS(20 * PI() / 180)
3533
					* COS(Article.latitude * PI() / 180)
3534
					* COS((50 - Article.longitude) * PI() / 180)
3535
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3536
		);
3537
 
3538
		$fields = array('id', 'distance');
3539
		$result = $this->Dbo->fields($Article, null, $fields);
3540
		$qs = $this->Dbo->startQuote;
3541
		$qe = $this->Dbo->endQuote;
3542
 
3543
		$this->assertEquals("{$qs}Article{$qe}.{$qs}id{$qe}", $result[0]);
3544
		$this->assertRegExp('/Article__distance/', $result[1]);
3545
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result[1]);
3546
		$this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result[1]);
3547
	}
3548
 
3549
/**
3550
 * test that execute runs queries.
3551
 *
3552
 * @return void
3553
 */
3554
	public function testExecute() {
3555
		$query = 'SELECT * FROM ' . $this->Dbo->fullTableName('articles') . ' WHERE 1 = 1';
3556
		$this->Dbo->took = null;
3557
		$this->Dbo->affected = null;
3558
		$result = $this->Dbo->execute($query, array('log' => false));
3559
		$this->assertNotNull($result, 'No query performed! %s');
3560
		$this->assertNull($this->Dbo->took, 'Stats were set %s');
3561
		$this->assertNull($this->Dbo->affected, 'Stats were set %s');
3562
 
3563
		$result = $this->Dbo->execute($query);
3564
		$this->assertNotNull($result, 'No query performed! %s');
3565
		$this->assertNotNull($this->Dbo->took, 'Stats were not set %s');
3566
		$this->assertNotNull($this->Dbo->affected, 'Stats were not set %s');
3567
	}
3568
 
3569
/**
3570
 * test a full example of using virtual fields
3571
 *
3572
 * @return void
3573
 */
3574
	public function testVirtualFieldsFetch() {
3575
		$this->loadFixtures('Article', 'Comment');
3576
 
3577
		$Article = ClassRegistry::init('Article');
3578
		$Article->virtualFields = array(
3579
			'comment_count' => 'SELECT COUNT(*) FROM ' . $this->Dbo->fullTableName('comments') .
3580
				' WHERE Article.id = ' . $this->Dbo->fullTableName('comments') . '.article_id'
3581
		);
3582
 
3583
		$conditions = array('comment_count >' => 2);
3584
		$query = 'SELECT ' . implode(',', $this->Dbo->fields($Article, null, array('id', 'comment_count'))) .
3585
				' FROM ' . $this->Dbo->fullTableName($Article) . ' Article ' . $this->Dbo->conditions($conditions, true, true, $Article);
3586
		$result = $this->Dbo->fetchAll($query);
3587
		$expected = array(array(
3588
			'Article' => array('id' => 1, 'comment_count' => 4)
3589
		));
3590
		$this->assertEquals($expected, $result);
3591
	}
3592
 
3593
/**
3594
 * test reading complex virtualFields with subqueries.
3595
 *
3596
 * @return void
3597
 */
3598
	public function testVirtualFieldsComplexRead() {
3599
		$this->loadFixtures('DataTest', 'Article', 'Comment', 'User', 'Tag', 'ArticlesTag');
3600
 
3601
		$Article = ClassRegistry::init('Article');
3602
		$commentTable = $this->Dbo->fullTableName('comments');
3603
		$Article = ClassRegistry::init('Article');
3604
		$Article->virtualFields = array(
3605
			'comment_count' => 'SELECT COUNT(*) FROM ' . $commentTable .
3606
				' AS Comment WHERE Article.id = Comment.article_id'
3607
		);
3608
		$result = $Article->find('all');
3609
		$this->assertTrue(count($result) > 0);
3610
		$this->assertTrue($result[0]['Article']['comment_count'] > 0);
3611
 
3612
		$DataTest = ClassRegistry::init('DataTest');
3613
		$DataTest->virtualFields = array(
3614
			'complicated' => 'ACOS(SIN(20 * PI() / 180)
3615
				* SIN(DataTest.float * PI() / 180)
3616
				+ COS(20 * PI() / 180)
3617
				* COS(DataTest.count * PI() / 180)
3618
				* COS((50 - DataTest.float) * PI() / 180)
3619
				) * 180 / PI() * 60 * 1.1515 * 1.609344'
3620
		);
3621
		$result = $DataTest->find('all');
3622
		$this->assertTrue(count($result) > 0);
3623
		$this->assertTrue($result[0]['DataTest']['complicated'] > 0);
3624
	}
3625
 
3626
/**
3627
 * testIntrospectType method
3628
 *
3629
 * @return void
3630
 */
3631
	public function testIntrospectType() {
3632
		$this->assertEquals('integer', $this->Dbo->introspectType(0));
3633
		$this->assertEquals('integer', $this->Dbo->introspectType(2));
3634
		$this->assertEquals('string', $this->Dbo->introspectType('2'));
3635
		$this->assertEquals('string', $this->Dbo->introspectType('2.2'));
3636
		$this->assertEquals('float', $this->Dbo->introspectType(2.2));
3637
		$this->assertEquals('string', $this->Dbo->introspectType('stringme'));
3638
		$this->assertEquals('string', $this->Dbo->introspectType('0stringme'));
3639
 
3640
		$data = array(2.2);
3641
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3642
 
3643
		$data = array('2.2');
3644
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3645
 
3646
		$data = array(2);
3647
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3648
 
3649
		$data = array('2');
3650
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3651
 
3652
		$data = array('string');
3653
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3654
 
3655
		$data = array(2.2, '2.2');
3656
		$this->assertEquals('float', $this->Dbo->introspectType($data));
3657
 
3658
		$data = array(2, '2');
3659
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3660
 
3661
		$data = array('string one', 'string two');
3662
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3663
 
3664
		$data = array('2.2', 3);
3665
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3666
 
3667
		$data = array('2.2', '0stringme');
3668
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3669
 
3670
		$data = array(2.2, 3);
3671
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3672
 
3673
		$data = array(2.2, '0stringme');
3674
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3675
 
3676
		$data = array(2, 'stringme');
3677
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3678
 
3679
		$data = array(2, '2.2', 'stringgme');
3680
		$this->assertEquals('string', $this->Dbo->introspectType($data));
3681
 
3682
		$data = array(2, '2.2');
3683
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3684
 
3685
		$data = array(2, 2.2);
3686
		$this->assertEquals('integer', $this->Dbo->introspectType($data));
3687
 
3688
		// null
3689
		$result = $this->Dbo->value(null, 'boolean');
3690
		$this->assertEquals('NULL', $result);
3691
 
3692
		// EMPTY STRING
3693
		$result = $this->Dbo->value('', 'boolean');
3694
		$this->assertEquals("'0'", $result);
3695
 
3696
		// BOOLEAN
3697
		$result = $this->Dbo->value('true', 'boolean');
3698
		$this->assertEquals("'1'", $result);
3699
 
3700
		$result = $this->Dbo->value('false', 'boolean');
3701
		$this->assertEquals("'1'", $result);
3702
 
3703
		$result = $this->Dbo->value(true, 'boolean');
3704
		$this->assertEquals("'1'", $result);
3705
 
3706
		$result = $this->Dbo->value(false, 'boolean');
3707
		$this->assertEquals("'0'", $result);
3708
 
3709
		$result = $this->Dbo->value(1, 'boolean');
3710
		$this->assertEquals("'1'", $result);
3711
 
3712
		$result = $this->Dbo->value(0, 'boolean');
3713
		$this->assertEquals("'0'", $result);
3714
 
3715
		$result = $this->Dbo->value('abc', 'boolean');
3716
		$this->assertEquals("'1'", $result);
3717
 
3718
		$result = $this->Dbo->value(1.234, 'boolean');
3719
		$this->assertEquals("'1'", $result);
3720
 
3721
		$result = $this->Dbo->value('1.234e05', 'boolean');
3722
		$this->assertEquals("'1'", $result);
3723
 
3724
		// NUMBERS
3725
		$result = $this->Dbo->value(123, 'integer');
3726
		$this->assertEquals(123, $result);
3727
 
3728
		$result = $this->Dbo->value('123', 'integer');
3729
		$this->assertEquals('123', $result);
3730
 
3731
		$result = $this->Dbo->value('0123', 'integer');
3732
		$this->assertEquals("'0123'", $result);
3733
 
3734
		$result = $this->Dbo->value('0x123ABC', 'integer');
3735
		$this->assertEquals("'0x123ABC'", $result);
3736
 
3737
		$result = $this->Dbo->value('0x123', 'integer');
3738
		$this->assertEquals("'0x123'", $result);
3739
 
3740
		$result = $this->Dbo->value(1.234, 'float');
3741
		$this->assertEquals(1.234, $result);
3742
 
3743
		$result = $this->Dbo->value('1.234', 'float');
3744
		$this->assertEquals('1.234', $result);
3745
 
3746
		$result = $this->Dbo->value(' 1.234 ', 'float');
3747
		$this->assertEquals("' 1.234 '", $result);
3748
 
3749
		$result = $this->Dbo->value('1.234e05', 'float');
3750
		$this->assertEquals("'1.234e05'", $result);
3751
 
3752
		$result = $this->Dbo->value('1.234e+5', 'float');
3753
		$this->assertEquals("'1.234e+5'", $result);
3754
 
3755
		$result = $this->Dbo->value('1,234', 'float');
3756
		$this->assertEquals("'1,234'", $result);
3757
 
3758
		$result = $this->Dbo->value('FFF', 'integer');
3759
		$this->assertEquals("'FFF'", $result);
3760
 
3761
		$result = $this->Dbo->value('abc', 'integer');
3762
		$this->assertEquals("'abc'", $result);
3763
 
3764
		// STRINGS
3765
		$result = $this->Dbo->value('123', 'string');
3766
		$this->assertEquals("'123'", $result);
3767
 
3768
		$result = $this->Dbo->value(123, 'string');
3769
		$this->assertEquals("'123'", $result);
3770
 
3771
		$result = $this->Dbo->value(1.234, 'string');
3772
		$this->assertEquals("'1.234'", $result);
3773
 
3774
		$result = $this->Dbo->value('abc', 'string');
3775
		$this->assertEquals("'abc'", $result);
3776
 
3777
		$result = $this->Dbo->value(' abc ', 'string');
3778
		$this->assertEquals("' abc '", $result);
3779
 
3780
		$result = $this->Dbo->value('a bc', 'string');
3781
		$this->assertEquals("'a bc'", $result);
3782
	}
3783
 
3784
/**
3785
 * testRealQueries method
3786
 *
3787
 * @return void
3788
 */
3789
	public function testRealQueries() {
3790
		$this->loadFixtures('Apple', 'Article', 'User', 'Comment', 'Tag', 'Sample', 'ArticlesTag');
3791
 
3792
		$Apple = ClassRegistry::init('Apple');
3793
		$Article = ClassRegistry::init('Article');
3794
 
3795
		$result = $this->Dbo->rawQuery('SELECT color, name FROM ' . $this->Dbo->fullTableName('apples'));
3796
		$this->assertTrue(!empty($result));
3797
 
3798
		$result = $this->Dbo->fetchRow($result);
3799
		$expected = array($this->Dbo->fullTableName('apples', false, false) => array(
3800
			'color' => 'Red 1',
3801
			'name' => 'Red Apple 1'
3802
		));
3803
		$this->assertEquals($expected, $result);
3804
 
3805
		$result = $this->Dbo->fetchAll('SELECT name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
3806
		$expected = array(
3807
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Red Apple 1')),
3808
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Bright Red Apple')),
3809
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'green blue')),
3810
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Test Name')),
3811
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Blue Green')),
3812
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'My new apple')),
3813
			array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Some odd color'))
3814
		);
3815
		$this->assertEquals($expected, $result);
3816
 
3817
		$result = $this->Dbo->field($this->Dbo->fullTableName('apples', false, false), 'SELECT color, name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
3818
		$expected = array(
3819
			'color' => 'Red 1',
3820
			'name' => 'Red Apple 1'
3821
		);
3822
		$this->assertEquals($expected, $result);
3823
 
3824
		$Apple->unbindModel(array(), false);
3825
		$result = $this->Dbo->read($Apple, array(
3826
			'fields' => array($Apple->escapeField('name')),
3827
			'conditions' => null,
3828
			'recursive' => -1
3829
		));
3830
		$expected = array(
3831
			array('Apple' => array('name' => 'Red Apple 1')),
3832
			array('Apple' => array('name' => 'Bright Red Apple')),
3833
			array('Apple' => array('name' => 'green blue')),
3834
			array('Apple' => array('name' => 'Test Name')),
3835
			array('Apple' => array('name' => 'Blue Green')),
3836
			array('Apple' => array('name' => 'My new apple')),
3837
			array('Apple' => array('name' => 'Some odd color'))
3838
		);
3839
		$this->assertEquals($expected, $result);
3840
 
3841
		$result = $this->Dbo->read($Article, array(
3842
			'fields' => array('id', 'user_id', 'title'),
3843
			'conditions' => null,
3844
			'recursive' => 1
3845
		));
3846
 
3847
		$this->assertTrue(Set::matches('/Article[id=1]', $result));
3848
		$this->assertTrue(Set::matches('/Comment[id=1]', $result));
3849
		$this->assertTrue(Set::matches('/Comment[id=2]', $result));
3850
		$this->assertFalse(Set::matches('/Comment[id=10]', $result));
3851
	}
3852
 
3853
/**
3854
 * @expectedException MissingConnectionException
3855
 * @return void
3856
 */
3857
	public function testExceptionOnBrokenConnection() {
3858
		new Mysql(array(
3859
			'driver' => 'mysql',
3860
			'host' => 'imaginary_host',
3861
			'login' => 'mark',
3862
			'password' => 'inyurdatabase',
3863
			'database' => 'imaginary'
3864
		));
3865
	}
3866
 
3867
/**
3868
 * testStatements method
3869
 *
3870
 * @return void
3871
 */
3872
	public function testUpdateStatements() {
3873
		$this->loadFixtures('Article', 'User');
3874
		$test = ConnectionManager::getDatasource('test');
3875
		$db = $test->config['database'];
3876
 
3877
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
3878
 
3879
		$this->Dbo->expects($this->at(0))->method('execute')
3880
			->with("UPDATE `$db`.`articles` SET `field1` = 'value1'  WHERE 1 = 1");
3881
 
3882
		$this->Dbo->expects($this->at(1))->method('execute')
3883
			->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
3884
				"(`Article`.`user_id` = `User`.`id`)" .
3885
				" SET `Article`.`field1` = 2  WHERE 2=2");
3886
 
3887
		$this->Dbo->expects($this->at(2))->method('execute')
3888
			->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
3889
				"(`Article`.`user_id` = `User`.`id`)" .
3890
				" SET `Article`.`field1` = 'value'  WHERE `index` = 'val'");
3891
 
3892
		$Article = new Article();
3893
 
3894
		$this->Dbo->update($Article, array('field1'), array('value1'));
3895
		$this->Dbo->update($Article, array('field1'), array('2'), '2=2');
3896
		$this->Dbo->update($Article, array('field1'), array("'value'"), array('index' => 'val'));
3897
	}
3898
 
3899
/**
3900
 * Test deletes with a mock.
3901
 *
3902
 * @return void
3903
 */
3904
	public function testDeleteStatements() {
3905
		$this->loadFixtures('Article', 'User');
3906
		$test = ConnectionManager::getDatasource('test');
3907
		$db = $test->config['database'];
3908
 
3909
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
3910
 
3911
		$this->Dbo->expects($this->at(0))->method('execute')
3912
			->with("DELETE  FROM `$db`.`articles`  WHERE 1 = 1");
3913
 
3914
		$this->Dbo->expects($this->at(1))->method('execute')
3915
			->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
3916
				"ON (`Article`.`user_id` = `User`.`id`)" .
3917
				"  WHERE 1 = 1");
3918
 
3919
		$this->Dbo->expects($this->at(2))->method('execute')
3920
			->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
3921
				"ON (`Article`.`user_id` = `User`.`id`)" .
3922
				"  WHERE 2=2");
3923
		$Article = new Article();
3924
 
3925
		$this->Dbo->delete($Article);
3926
		$this->Dbo->delete($Article, true);
3927
		$this->Dbo->delete($Article, '2=2');
3928
	}
3929
 
3930
/**
3931
 * Test truncate with a mock.
3932
 *
3933
 * @return void
3934
 */
3935
	public function testTruncateStatements() {
3936
		$this->loadFixtures('Article', 'User');
3937
		$db = ConnectionManager::getDatasource('test');
3938
		$schema = $db->config['database'];
3939
		$Article = new Article();
3940
 
3941
		$this->Dbo = $this->getMock('Mysql', array('execute'), array($db->config));
3942
 
3943
		$this->Dbo->expects($this->at(0))->method('execute')
3944
			->with("TRUNCATE TABLE `$schema`.`articles`");
3945
		$this->Dbo->truncate($Article);
3946
 
3947
		$this->Dbo->expects($this->at(0))->method('execute')
3948
			->with("TRUNCATE TABLE `$schema`.`articles`");
3949
		$this->Dbo->truncate('articles');
3950
 
3951
		// #2355: prevent duplicate prefix
3952
		$this->Dbo->config['prefix'] = 'tbl_';
3953
		$Article->tablePrefix = 'tbl_';
3954
		$this->Dbo->expects($this->at(0))->method('execute')
3955
			->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
3956
		$this->Dbo->truncate($Article);
3957
 
3958
		$this->Dbo->expects($this->at(0))->method('execute')
3959
			->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
3960
		$this->Dbo->truncate('articles');
3961
	}
3962
 
3963
/**
3964
 * Test nested transaction
3965
 *
3966
 * @return void
3967
 */
3968
	public function testNestedTransaction() {
3969
		$nested = $this->Dbo->useNestedTransactions;
3970
		$this->Dbo->useNestedTransactions = true;
3971
		if ($this->Dbo->nestedTransactionSupported() === false) {
3972
			$this->Dbo->useNestedTransactions = $nested;
3973
			$this->skipIf(true, 'The MySQL server do not support nested transaction');
3974
		}
3975
 
3976
		$this->loadFixtures('Inno');
3977
		$model = ClassRegistry::init('Inno');
3978
		$model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
3979
		$model->cacheQueries = false;
3980
		$this->Dbo->cacheMethods = false;
3981
 
3982
		$this->assertTrue($this->Dbo->begin());
3983
		$this->assertNotEmpty($model->read(null, 1));
3984
 
3985
		$this->assertTrue($this->Dbo->begin());
3986
		$this->assertTrue($model->delete(1));
3987
		$this->assertEmpty($model->read(null, 1));
3988
		$this->assertTrue($this->Dbo->rollback());
3989
		$this->assertNotEmpty($model->read(null, 1));
3990
 
3991
		$this->assertTrue($this->Dbo->begin());
3992
		$this->assertTrue($model->delete(1));
3993
		$this->assertEmpty($model->read(null, 1));
3994
		$this->assertTrue($this->Dbo->commit());
3995
		$this->assertEmpty($model->read(null, 1));
3996
 
3997
		$this->assertTrue($this->Dbo->rollback());
3998
		$this->assertNotEmpty($model->read(null, 1));
3999
 
4000
		$this->Dbo->useNestedTransactions = $nested;
4001
	}
4002
 
4003
}