Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13532 anikendra 1
<?php
2
/**
3
 * DboSqliteTest 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('Sqlite', 'Model/Datasource/Database');
22
 
23
require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
24
 
25
/**
26
 * DboSqliteTestDb class
27
 *
28
 * @package       Cake.Test.Case.Model.Datasource.Database
29
 */
30
class DboSqliteTestDb extends Sqlite {
31
 
32
/**
33
 * simulated property
34
 *
35
 * @var array
36
 */
37
	public $simulated = array();
38
 
39
/**
40
 * execute method
41
 *
42
 * @param mixed $sql
43
 * @return void
44
 */
45
	protected function _execute($sql, $params = array(), $prepareOptions = array()) {
46
		$this->simulated[] = $sql;
47
		return null;
48
	}
49
 
50
/**
51
 * getLastQuery method
52
 *
53
 * @return void
54
 */
55
	public function getLastQuery() {
56
		return $this->simulated[count($this->simulated) - 1];
57
	}
58
 
59
}
60
 
61
/**
62
 * DboSqliteTest class
63
 *
64
 * @package       Cake.Test.Case.Model.Datasource.Database
65
 */
66
class SqliteTest extends CakeTestCase {
67
 
68
/**
69
 * Do not automatically load fixtures for each test, they will be loaded manually using CakeTestCase::loadFixtures
70
 *
71
 * @var boolean
72
 */
73
	public $autoFixtures = false;
74
 
75
/**
76
 * Fixtures
77
 *
78
 * @var object
79
 */
80
	public $fixtures = array('core.user', 'core.uuid', 'core.datatype');
81
 
82
/**
83
 * Actual DB connection used in testing
84
 *
85
 * @var DboSource
86
 */
87
	public $Dbo = null;
88
 
89
/**
90
 * Sets up a Dbo class instance for testing
91
 *
92
 */
93
	public function setUp() {
94
		parent::setUp();
95
		Configure::write('Cache.disable', true);
96
		$this->Dbo = ConnectionManager::getDataSource('test');
97
		if (!$this->Dbo instanceof Sqlite) {
98
			$this->markTestSkipped('The Sqlite extension is not available.');
99
		}
100
	}
101
 
102
/**
103
 * Sets up a Dbo class instance for testing
104
 *
105
 */
106
	public function tearDown() {
107
		parent::tearDown();
108
		Configure::write('Cache.disable', false);
109
	}
110
 
111
/**
112
 * Tests that SELECT queries from DboSqlite::listSources() are not cached
113
 *
114
 */
115
	public function testTableListCacheDisabling() {
116
		$this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
117
 
118
		$this->Dbo->query('CREATE TABLE foo_test (test VARCHAR(255))');
119
		$this->assertTrue(in_array('foo_test', $this->Dbo->listSources()));
120
 
121
		$this->Dbo->cacheSources = false;
122
		$this->Dbo->query('DROP TABLE foo_test');
123
		$this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
124
	}
125
 
126
/**
127
 * test Index introspection.
128
 *
129
 * @return void
130
 */
131
	public function testIndex() {
132
		$name = $this->Dbo->fullTableName('with_a_key', false, false);
133
		$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" int(11) PRIMARY KEY, "bool" int(1), "small_char" varchar(50), "description" varchar(40) );');
134
		$this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
135
		$this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
136
		$expected = array(
137
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
138
			'pointless_bool' => array('column' => 'bool', 'unique' => 0),
139
			'char_index' => array('column' => 'small_char', 'unique' => 1),
140
 
141
		);
142
		$result = $this->Dbo->index($name);
143
		$this->assertEquals($expected, $result);
144
		$this->Dbo->query('DROP TABLE ' . $name);
145
 
146
		$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" int(11) PRIMARY KEY, "bool" int(1), "small_char" varchar(50), "description" varchar(40) );');
147
		$this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
148
		$expected = array(
149
			'PRIMARY' => array('column' => 'id', 'unique' => 1),
150
			'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
151
		);
152
		$result = $this->Dbo->index($name);
153
		$this->assertEquals($expected, $result);
154
		$this->Dbo->query('DROP TABLE ' . $name);
155
	}
156
 
157
/**
158
 * Tests that cached table descriptions are saved under the sanitized key name
159
 *
160
 */
161
	public function testCacheKeyName() {
162
		Configure::write('Cache.disable', false);
163
 
164
		$dbName = 'db' . rand() . '$(*%&).db';
165
		$this->assertFalse(file_exists(TMP . $dbName));
166
 
167
		$db = new Sqlite(array_merge($this->Dbo->config, array('database' => TMP . $dbName)));
168
		$this->assertTrue(file_exists(TMP . $dbName));
169
 
170
		$db->execute("CREATE TABLE test_list (id VARCHAR(255));");
171
 
172
		$db->cacheSources = true;
173
		$this->assertEquals(array('test_list'), $db->listSources());
174
		$db->cacheSources = false;
175
 
176
		$fileName = '_' . preg_replace('/[^A-Za-z0-9_\-+]/', '_', TMP . $dbName) . '_list';
177
 
178
		$result = Cache::read($fileName, '_cake_model_');
179
		$this->assertEquals(array('test_list'), $result);
180
 
181
		Cache::delete($fileName, '_cake_model_');
182
		Configure::write('Cache.disable', true);
183
	}
184
 
185
/**
186
 * test building columns with SQLite
187
 *
188
 * @return void
189
 */
190
	public function testBuildColumn() {
191
		$data = array(
192
			'name' => 'int_field',
193
			'type' => 'integer',
194
			'null' => false,
195
		);
196
		$result = $this->Dbo->buildColumn($data);
197
		$expected = '"int_field" integer NOT NULL';
198
		$this->assertEquals($expected, $result);
199
 
200
		$data = array(
201
			'name' => 'name',
202
			'type' => 'string',
203
			'length' => 20,
204
			'null' => false,
205
		);
206
		$result = $this->Dbo->buildColumn($data);
207
		$expected = '"name" varchar(20) NOT NULL';
208
		$this->assertEquals($expected, $result);
209
 
210
		$data = array(
211
			'name' => 'testName',
212
			'type' => 'string',
213
			'length' => 20,
214
			'default' => null,
215
			'null' => true,
216
			'collate' => 'NOCASE'
217
		);
218
		$result = $this->Dbo->buildColumn($data);
219
		$expected = '"testName" varchar(20) DEFAULT NULL COLLATE NOCASE';
220
		$this->assertEquals($expected, $result);
221
 
222
		$data = array(
223
			'name' => 'testName',
224
			'type' => 'string',
225
			'length' => 20,
226
			'default' => 'test-value',
227
			'null' => false,
228
		);
229
		$result = $this->Dbo->buildColumn($data);
230
		$expected = '"testName" varchar(20) DEFAULT \'test-value\' NOT NULL';
231
		$this->assertEquals($expected, $result);
232
 
233
		$data = array(
234
			'name' => 'testName',
235
			'type' => 'integer',
236
			'length' => 10,
237
			'default' => 10,
238
			'null' => false,
239
		);
240
		$result = $this->Dbo->buildColumn($data);
241
		$expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
242
		$this->assertEquals($expected, $result);
243
 
244
		$data = array(
245
			'name' => 'testName',
246
			'type' => 'integer',
247
			'length' => 10,
248
			'default' => 10,
249
			'null' => false,
250
			'collate' => 'BADVALUE'
251
		);
252
		$result = $this->Dbo->buildColumn($data);
253
		$expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
254
		$this->assertEquals($expected, $result);
255
 
256
		$data = array(
257
			'name' => 'huge',
258
			'type' => 'biginteger',
259
			'length' => 20,
260
			'null' => false,
261
		);
262
		$result = $this->Dbo->buildColumn($data);
263
		$expected = '"huge" bigint(20) NOT NULL';
264
		$this->assertEquals($expected, $result);
265
 
266
		$data = array(
267
			'name' => 'id',
268
			'type' => 'biginteger',
269
			'length' => 20,
270
			'null' => false,
271
			'key' => 'primary',
272
		);
273
		$result = $this->Dbo->buildColumn($data);
274
		$expected = '"id" bigint(20) NOT NULL PRIMARY KEY';
275
		$this->assertEquals($expected, $result);
276
	}
277
 
278
/**
279
 * test describe() and normal results.
280
 *
281
 * @return void
282
 */
283
	public function testDescribe() {
284
		$this->loadFixtures('User');
285
		$Model = new Model(array(
286
			'name' => 'User',
287
			'ds' => 'test',
288
			'table' => 'users'
289
		));
290
 
291
		$this->Dbo->cacheSources = true;
292
		Configure::write('Cache.disable', false);
293
 
294
		$result = $this->Dbo->describe($Model);
295
		$expected = array(
296
			'id' => array(
297
				'type' => 'integer',
298
				'key' => 'primary',
299
				'null' => false,
300
				'default' => null,
301
				'length' => 11
302
			),
303
			'user' => array(
304
				'type' => 'string',
305
				'length' => 255,
306
				'null' => true,
307
				'default' => null
308
			),
309
			'password' => array(
310
				'type' => 'string',
311
				'length' => 255,
312
				'null' => true,
313
				'default' => null
314
			),
315
			'created' => array(
316
				'type' => 'datetime',
317
				'null' => true,
318
				'default' => null,
319
				'length' => null,
320
			),
321
			'updated' => array(
322
				'type' => 'datetime',
323
				'null' => true,
324
				'default' => null,
325
				'length' => null,
326
			)
327
		);
328
		$this->assertEquals($expected, $result);
329
 
330
		$result = $this->Dbo->describe($Model->useTable);
331
		$this->assertEquals($expected, $result);
332
 
333
		$result = Cache::read('test_users', '_cake_model_');
334
		$this->assertEquals($expected, $result);
335
	}
336
 
337
/**
338
 * Test that datatypes are reflected
339
 *
340
 * @return void
341
 */
342
	public function testDatatypes() {
343
		$this->loadFixtures('Datatype');
344
		$Model = new Model(array(
345
			'name' => 'Datatype',
346
			'ds' => 'test',
347
			'table' => 'datatypes'
348
		));
349
		$result = $this->Dbo->describe($Model);
350
		$expected = array(
351
			'id' => array(
352
				'type' => 'integer',
353
				'null' => false,
354
				'default' => '',
355
				'length' => 11,
356
				'key' => 'primary',
357
			),
358
			'float_field' => array(
359
				'type' => 'float',
360
				'null' => false,
361
				'default' => '',
362
				'length' => '5,2',
363
			),
364
			'huge_int' => array(
365
				'type' => 'biginteger',
366
				'null' => true,
367
				'default' => null,
368
				'length' => 20,
369
			),
370
			'bool' => array(
371
				'type' => 'boolean',
372
				'null' => false,
373
				'default' => '0',
374
				'length' => null
375
			),
376
		);
377
		$this->assertSame($expected, $result);
378
	}
379
 
380
/**
381
 * test that describe does not corrupt UUID primary keys
382
 *
383
 * @return void
384
 */
385
	public function testDescribeWithUuidPrimaryKey() {
386
		$tableName = 'uuid_tests';
387
		$this->Dbo->query("CREATE TABLE {$tableName} (id VARCHAR(36) PRIMARY KEY, name VARCHAR, created DATETIME, modified DATETIME)");
388
		$Model = new Model(array('name' => 'UuidTest', 'ds' => 'test', 'table' => 'uuid_tests'));
389
		$result = $this->Dbo->describe($Model);
390
		$expected = array(
391
			'type' => 'string',
392
			'length' => 36,
393
			'null' => false,
394
			'default' => null,
395
			'key' => 'primary',
396
		);
397
		$this->assertEquals($expected, $result['id']);
398
		$this->Dbo->query('DROP TABLE ' . $tableName);
399
 
400
		$tableName = 'uuid_tests';
401
		$this->Dbo->query("CREATE TABLE {$tableName} (id CHAR(36) PRIMARY KEY, name VARCHAR, created DATETIME, modified DATETIME)");
402
		$Model = new Model(array('name' => 'UuidTest', 'ds' => 'test', 'table' => 'uuid_tests'));
403
		$result = $this->Dbo->describe($Model);
404
		$expected = array(
405
			'type' => 'string',
406
			'length' => 36,
407
			'null' => false,
408
			'default' => null,
409
			'key' => 'primary',
410
		);
411
		$this->assertEquals($expected, $result['id']);
412
		$this->Dbo->query('DROP TABLE ' . $tableName);
413
	}
414
 
415
/**
416
 * Test virtualFields with functions.
417
 *
418
 * @return void
419
 */
420
	public function testVirtualFieldWithFunction() {
421
		$this->loadFixtures('User');
422
		$User = ClassRegistry::init('User');
423
		$User->virtualFields = array('name' => 'SUBSTR(User.user, 5, LENGTH(User.user) - 4)');
424
 
425
		$result = $User->find('first', array(
426
			'conditions' => array('User.user' => 'garrett')
427
		));
428
		$this->assertEquals('ett', $result['User']['name']);
429
	}
430
 
431
/**
432
 * Test that records can be inserted with UUID primary keys, and
433
 * that the primary key is not blank
434
 *
435
 * @return void
436
 */
437
	public function testUuidPrimaryKeyInsertion() {
438
		$this->loadFixtures('Uuid');
439
		$Model = ClassRegistry::init('Uuid');
440
 
441
		$data = array(
442
			'title' => 'A UUID should work',
443
			'count' => 10
444
		);
445
		$Model->create($data);
446
		$this->assertTrue((bool)$Model->save());
447
		$result = $Model->read();
448
 
449
		$this->assertEquals($data['title'], $result['Uuid']['title']);
450
		$this->assertTrue(Validation::uuid($result['Uuid']['id']), 'Not a UUID');
451
	}
452
 
453
/**
454
 * Test nested transaction
455
 *
456
 * @return void
457
 */
458
	public function testNestedTransaction() {
459
		$this->skipIf($this->Dbo->nestedTransactionSupported() === false, 'The Sqlite version do not support nested transaction');
460
 
461
		$this->loadFixtures('User');
462
		$model = new User();
463
		$model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
464
		$model->cacheQueries = false;
465
		$this->Dbo->cacheMethods = false;
466
 
467
		$this->assertTrue($this->Dbo->begin());
468
		$this->assertNotEmpty($model->read(null, 1));
469
 
470
		$this->assertTrue($this->Dbo->begin());
471
		$this->assertTrue($model->delete(1));
472
		$this->assertEmpty($model->read(null, 1));
473
		$this->assertTrue($this->Dbo->rollback());
474
		$this->assertNotEmpty($model->read(null, 1));
475
 
476
		$this->assertTrue($this->Dbo->begin());
477
		$this->assertTrue($model->delete(1));
478
		$this->assertEmpty($model->read(null, 1));
479
		$this->assertTrue($this->Dbo->commit());
480
		$this->assertEmpty($model->read(null, 1));
481
 
482
		$this->assertTrue($this->Dbo->rollback());
483
		$this->assertNotEmpty($model->read(null, 1));
484
	}
485
 
486
/**
487
 * Test the limit function.
488
 *
489
 * @return void
490
 */
491
	public function testLimit() {
492
		$db = $this->Dbo;
493
 
494
		$result = $db->limit('0');
495
		$this->assertNull($result);
496
 
497
		$result = $db->limit('10');
498
		$this->assertEquals(' LIMIT 10', $result);
499
 
500
		$result = $db->limit('FARTS', 'BOOGERS');
501
		$this->assertEquals(' LIMIT 0 OFFSET 0', $result);
502
 
503
		$result = $db->limit(20, 10);
504
		$this->assertEquals(' LIMIT 20 OFFSET 10', $result);
505
 
506
		$result = $db->limit(10, 300000000000000000000000000000);
507
		$scientificNotation = sprintf('%.1E', 300000000000000000000000000000);
508
		$this->assertNotContains($scientificNotation, $result);
509
	}
510
 
511
}