Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

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