mirror of
https://github.com/yiisoft/yii2.git
synced 2026-03-21 14:37:21 +01:00
added test to check support for setting PDO::ATTR_CASE and fetching table schemas fixed fetching table schemas for mysql when PDO::ATTR_CASE is set added tests for oci fixed fetching composite fks for oci improvements in oci schema parsing removed autoIncrement detection fro oci and added test to verify that implement batchInsert for oci fix detecting IntegrityException for oci fixed creating raw sql by skipping object and resource params fix command test failing for sqlite
404 lines
14 KiB
PHP
404 lines
14 KiB
PHP
<?php
|
|
|
|
namespace yiiunit\framework\db;
|
|
|
|
use yii\caching\FileCache;
|
|
use yii\db\Connection;
|
|
use yii\db\DataReader;
|
|
|
|
/**
|
|
* @group db
|
|
* @group mysql
|
|
*/
|
|
class CommandTest extends DatabaseTestCase
|
|
{
|
|
public function testConstruct()
|
|
{
|
|
$db = $this->getConnection(false);
|
|
|
|
// null
|
|
$command = $db->createCommand();
|
|
$this->assertEquals(null, $command->sql);
|
|
|
|
// string
|
|
$sql = 'SELECT * FROM customer';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertEquals($sql, $command->sql);
|
|
}
|
|
|
|
public function testGetSetSql()
|
|
{
|
|
$db = $this->getConnection(false);
|
|
|
|
$sql = 'SELECT * FROM customer';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertEquals($sql, $command->sql);
|
|
|
|
$sql2 = 'SELECT * FROM order';
|
|
$command->sql = $sql2;
|
|
$this->assertEquals($sql2, $command->sql);
|
|
}
|
|
|
|
public function testAutoQuoting()
|
|
{
|
|
$db = $this->getConnection(false);
|
|
|
|
$sql = 'SELECT [[id]], [[t.name]] FROM {{customer}} t';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertEquals("SELECT `id`, `t`.`name` FROM `customer` t", $command->sql);
|
|
}
|
|
|
|
public function testPrepareCancel()
|
|
{
|
|
$db = $this->getConnection(false);
|
|
|
|
$command = $db->createCommand('SELECT * FROM {{customer}}');
|
|
$this->assertEquals(null, $command->pdoStatement);
|
|
$command->prepare();
|
|
$this->assertNotEquals(null, $command->pdoStatement);
|
|
$command->cancel();
|
|
$this->assertEquals(null, $command->pdoStatement);
|
|
}
|
|
|
|
public function testExecute()
|
|
{
|
|
$db = $this->getConnection();
|
|
|
|
$sql = 'INSERT INTO {{customer}}([[email]], [[name]], [[address]]) VALUES (\'user4@example.com\', \'user4\', \'address4\')';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertEquals(1, $command->execute());
|
|
|
|
$sql = 'SELECT COUNT(*) FROM {{customer}} WHERE [[name]] = \'user4\'';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertEquals(1, $command->queryScalar());
|
|
|
|
$command = $db->createCommand('bad SQL');
|
|
$this->setExpectedException('\yii\db\Exception');
|
|
$command->execute();
|
|
}
|
|
|
|
public function testQuery()
|
|
{
|
|
$db = $this->getConnection();
|
|
|
|
// query
|
|
$sql = 'SELECT * FROM {{customer}}';
|
|
$reader = $db->createCommand($sql)->query();
|
|
$this->assertTrue($reader instanceof DataReader);
|
|
|
|
// queryAll
|
|
$rows = $db->createCommand('SELECT * FROM {{customer}}')->queryAll();
|
|
$this->assertEquals(3, count($rows));
|
|
$row = $rows[2];
|
|
$this->assertEquals(3, $row['id']);
|
|
$this->assertEquals('user3', $row['name']);
|
|
|
|
$rows = $db->createCommand('SELECT * FROM {{customer}} WHERE [[id]] = 10')->queryAll();
|
|
$this->assertEquals([], $rows);
|
|
|
|
// queryOne
|
|
$sql = 'SELECT * FROM {{customer}} ORDER BY [[id]]';
|
|
$row = $db->createCommand($sql)->queryOne();
|
|
$this->assertEquals(1, $row['id']);
|
|
$this->assertEquals('user1', $row['name']);
|
|
|
|
$sql = 'SELECT * FROM {{customer}} ORDER BY [[id]]';
|
|
$command = $db->createCommand($sql);
|
|
$command->prepare();
|
|
$row = $command->queryOne();
|
|
$this->assertEquals(1, $row['id']);
|
|
$this->assertEquals('user1', $row['name']);
|
|
|
|
$sql = 'SELECT * FROM {{customer}} WHERE [[id]] = 10';
|
|
$command = $db->createCommand($sql);
|
|
$this->assertFalse($command->queryOne());
|
|
|
|
// queryColumn
|
|
$sql = 'SELECT * FROM {{customer}}';
|
|
$column = $db->createCommand($sql)->queryColumn();
|
|
$this->assertEquals(range(1, 3), $column);
|
|
|
|
$command = $db->createCommand('SELECT [[id]] FROM {{customer}} WHERE [[id]] = 10');
|
|
$this->assertEquals([], $command->queryColumn());
|
|
|
|
// queryScalar
|
|
$sql = 'SELECT * FROM {{customer}} ORDER BY [[id]]';
|
|
$this->assertEquals($db->createCommand($sql)->queryScalar(), 1);
|
|
|
|
$sql = 'SELECT [[id]] FROM {{customer}} ORDER BY [[id]]';
|
|
$command = $db->createCommand($sql);
|
|
$command->prepare();
|
|
$this->assertEquals(1, $command->queryScalar());
|
|
|
|
$command = $db->createCommand('SELECT [[id]] FROM {{customer}} WHERE [[id]] = 10');
|
|
$this->assertFalse($command->queryScalar());
|
|
|
|
$command = $db->createCommand('bad SQL');
|
|
$this->setExpectedException('\yii\db\Exception');
|
|
$command->query();
|
|
}
|
|
|
|
public function testBindParamValue()
|
|
{
|
|
$db = $this->getConnection();
|
|
|
|
// bindParam
|
|
$sql = 'INSERT INTO {{customer}}([[email]], [[name]], [[address]]) VALUES (:email, :name, :address)';
|
|
$command = $db->createCommand($sql);
|
|
$email = 'user4@example.com';
|
|
$name = 'user4';
|
|
$address = 'address4';
|
|
$command->bindParam(':email', $email);
|
|
$command->bindParam(':name', $name);
|
|
$command->bindParam(':address', $address);
|
|
$command->execute();
|
|
|
|
$sql = 'SELECT [[name]] FROM {{customer}} WHERE [[email]] = :email';
|
|
$command = $db->createCommand($sql);
|
|
$command->bindParam(':email', $email);
|
|
$this->assertEquals($name, $command->queryScalar());
|
|
|
|
$sql = <<<SQL
|
|
INSERT INTO {{type}} ([[int_col]], [[char_col]], [[float_col]], [[blob_col]], [[numeric_col]], [[bool_col]])
|
|
VALUES (:int_col, :char_col, :float_col, :blob_col, :numeric_col, :bool_col)
|
|
SQL;
|
|
$command = $db->createCommand($sql);
|
|
$intCol = 123;
|
|
$charCol = str_repeat('abc', 33) . 'x'; // a 100 char string
|
|
$boolCol = false;
|
|
$command->bindParam(':int_col', $intCol, \PDO::PARAM_INT);
|
|
$command->bindParam(':char_col', $charCol);
|
|
$command->bindParam(':bool_col', $boolCol, \PDO::PARAM_BOOL);
|
|
if ($this->driverName === 'oci') {
|
|
// can't bind floats without support from a custom PDO driver
|
|
$floatCol = 2;
|
|
$numericCol = 3;
|
|
// can't use blobs without support from a custom PDO driver
|
|
$blobCol = null;
|
|
$command->bindParam(':float_col', $floatCol, \PDO::PARAM_INT);
|
|
$command->bindParam(':numeric_col', $numericCol, \PDO::PARAM_INT);
|
|
$command->bindParam(':blob_col', $blobCol);
|
|
} else {
|
|
$floatCol = 1.23;
|
|
$numericCol = '1.23';
|
|
$blobCol = "\x10\x11\x12";
|
|
$command->bindParam(':float_col', $floatCol);
|
|
$command->bindParam(':numeric_col', $numericCol);
|
|
$command->bindParam(':blob_col', $blobCol);
|
|
}
|
|
$this->assertEquals(1, $command->execute());
|
|
|
|
$command = $db->createCommand('SELECT [[int_col]], [[char_col]], [[float_col]], [[blob_col]], [[numeric_col]], [[bool_col]] FROM {{type}}');
|
|
// $command->prepare();
|
|
// $command->pdoStatement->bindColumn('blob_col', $bc, \PDO::PARAM_LOB);
|
|
$row = $command->queryOne();
|
|
$this->assertEquals($intCol, $row['int_col']);
|
|
$this->assertEquals($charCol, $row['char_col']);
|
|
$this->assertEquals($floatCol, $row['float_col']);
|
|
if ($this->driverName === 'mysql' || $this->driverName === 'sqlite' || $this->driverName === 'oci') {
|
|
$this->assertEquals($blobCol, $row['blob_col']);
|
|
} else {
|
|
$this->assertTrue(is_resource($row['blob_col']));
|
|
$this->assertEquals($blobCol, stream_get_contents($row['blob_col']));
|
|
}
|
|
$this->assertEquals($numericCol, $row['numeric_col']);
|
|
if ($this->driverName === 'mysql' || (defined('HHVM_VERSION') && $this->driverName === 'sqlite') || $this->driverName === 'oci') {
|
|
$this->assertEquals($boolCol, (int) $row['bool_col']);
|
|
} else {
|
|
$this->assertEquals($boolCol, $row['bool_col']);
|
|
}
|
|
|
|
// bindValue
|
|
$sql = 'INSERT INTO {{customer}}([[email]], [[name]], [[address]]) VALUES (:email, \'user5\', \'address5\')';
|
|
$command = $db->createCommand($sql);
|
|
$command->bindValue(':email', 'user5@example.com');
|
|
$command->execute();
|
|
|
|
$sql = 'SELECT [[email]] FROM {{customer}} WHERE [[name]] = :name';
|
|
$command = $db->createCommand($sql);
|
|
$command->bindValue(':name', 'user5');
|
|
$this->assertEquals('user5@example.com', $command->queryScalar());
|
|
}
|
|
|
|
public function testFetchMode()
|
|
{
|
|
$db = $this->getConnection();
|
|
|
|
// default: FETCH_ASSOC
|
|
$sql = 'SELECT * FROM {{customer}}';
|
|
$command = $db->createCommand($sql);
|
|
$result = $command->queryOne();
|
|
$this->assertTrue(is_array($result) && isset($result['id']));
|
|
|
|
// FETCH_OBJ, customized via fetchMode property
|
|
$sql = 'SELECT * FROM {{customer}}';
|
|
$command = $db->createCommand($sql);
|
|
$command->fetchMode = \PDO::FETCH_OBJ;
|
|
$result = $command->queryOne();
|
|
$this->assertTrue(is_object($result));
|
|
|
|
// FETCH_NUM, customized in query method
|
|
$sql = 'SELECT * FROM {{customer}}';
|
|
$command = $db->createCommand($sql);
|
|
$result = $command->queryOne([], \PDO::FETCH_NUM);
|
|
$this->assertTrue(is_array($result) && isset($result[0]));
|
|
}
|
|
|
|
public function testBatchInsert()
|
|
{
|
|
$command = $this->getConnection()->createCommand();
|
|
$command->batchInsert(
|
|
'{{customer}}',
|
|
['email', 'name', 'address'],
|
|
[
|
|
['t1@example.com', 't1', 't1 address'],
|
|
['t2@example.com', null, false],
|
|
]
|
|
);
|
|
$this->assertEquals(2, $command->execute());
|
|
}
|
|
|
|
/*
|
|
public function testInsert()
|
|
{
|
|
}
|
|
|
|
public function testUpdate()
|
|
{
|
|
}
|
|
|
|
public function testDelete()
|
|
{
|
|
}
|
|
|
|
public function testCreateTable()
|
|
{
|
|
}
|
|
|
|
public function testRenameTable()
|
|
{
|
|
}
|
|
|
|
public function testDropTable()
|
|
{
|
|
}
|
|
|
|
public function testTruncateTable()
|
|
{
|
|
}
|
|
|
|
public function testAddColumn()
|
|
{
|
|
}
|
|
|
|
public function testDropColumn()
|
|
{
|
|
}
|
|
|
|
public function testRenameColumn()
|
|
{
|
|
}
|
|
|
|
public function testAlterColumn()
|
|
{
|
|
}
|
|
|
|
public function testAddForeignKey()
|
|
{
|
|
}
|
|
|
|
public function testDropForeignKey()
|
|
{
|
|
}
|
|
|
|
public function testCreateIndex()
|
|
{
|
|
}
|
|
|
|
public function testDropIndex()
|
|
{
|
|
}
|
|
*/
|
|
|
|
public function testIntegrityViolation()
|
|
{
|
|
$this->setExpectedException('\yii\db\IntegrityException');
|
|
|
|
$db = $this->getConnection();
|
|
|
|
$sql = 'INSERT INTO {{profile}}([[id]], [[description]]) VALUES (123, \'duplicate\')';
|
|
$command = $db->createCommand($sql);
|
|
$command->execute();
|
|
$command->execute();
|
|
}
|
|
|
|
public function testQueryCache()
|
|
{
|
|
$db = $this->getConnection();
|
|
$db->enableQueryCache = true;
|
|
$db->queryCache = new FileCache(['cachePath' => '@yiiunit/runtime/cache']);
|
|
$command = $db->createCommand('SELECT [[name]] FROM {{customer}} WHERE [[id]] = :id');
|
|
|
|
$this->assertEquals('user1', $command->bindValue(':id', 1)->queryScalar());
|
|
$update = $db->createCommand('UPDATE {{customer}} SET [[name]] = :name WHERE [[id]] = :id');
|
|
$update->bindValues([':id' => 1, ':name' => 'user11'])->execute();
|
|
$this->assertEquals('user11', $command->bindValue(':id', 1)->queryScalar());
|
|
|
|
$db->cache(function (Connection $db) use ($command, $update) {
|
|
$this->assertEquals('user2', $command->bindValue(':id', 2)->queryScalar());
|
|
$update->bindValues([':id' => 2, ':name' => 'user22'])->execute();
|
|
$this->assertEquals('user2', $command->bindValue(':id', 2)->queryScalar());
|
|
|
|
$db->noCache(function () use ($command) {
|
|
$this->assertEquals('user22', $command->bindValue(':id', 2)->queryScalar());
|
|
});
|
|
|
|
$this->assertEquals('user2', $command->bindValue(':id', 2)->queryScalar());
|
|
}, 10);
|
|
|
|
$db->enableQueryCache = false;
|
|
$db->cache(function ($db) use ($command, $update) {
|
|
$this->assertEquals('user22', $command->bindValue(':id', 2)->queryScalar());
|
|
$update->bindValues([':id' => 2, ':name' => 'user2'])->execute();
|
|
$this->assertEquals('user2', $command->bindValue(':id', 2)->queryScalar());
|
|
}, 10);
|
|
|
|
$db->enableQueryCache = true;
|
|
$command = $db->createCommand('SELECT [[name]] FROM {{customer}} WHERE [[id]] = :id')->cache();
|
|
$this->assertEquals('user11', $command->bindValue(':id', 1)->queryScalar());
|
|
$update->bindValues([':id' => 1, ':name' => 'user1'])->execute();
|
|
$this->assertEquals('user11', $command->bindValue(':id', 1)->queryScalar());
|
|
$this->assertEquals('user1', $command->noCache()->bindValue(':id', 1)->queryScalar());
|
|
|
|
$command = $db->createCommand('SELECT [[name]] FROM {{customer}} WHERE [[id]] = :id');
|
|
$db->cache(function (Connection $db) use ($command, $update) {
|
|
$this->assertEquals('user11', $command->bindValue(':id', 1)->queryScalar());
|
|
$this->assertEquals('user1', $command->noCache()->bindValue(':id', 1)->queryScalar());
|
|
}, 10);
|
|
}
|
|
|
|
public function testColumnCase()
|
|
{
|
|
$db = $this->getConnection(false);
|
|
$this->assertEquals(\PDO::CASE_NATURAL, $db->slavePdo->getAttribute(\PDO::ATTR_CASE));
|
|
|
|
$sql = 'SELECT [[customer_id]], [[total]] FROM {{order}}';
|
|
$rows = $db->createCommand($sql)->queryAll();
|
|
$this->assertTrue(isset($rows[0]));
|
|
$this->assertTrue(isset($rows[0]['customer_id']));
|
|
$this->assertTrue(isset($rows[0]['total']));
|
|
|
|
$db->slavePdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);
|
|
$rows = $db->createCommand($sql)->queryAll();
|
|
$this->assertTrue(isset($rows[0]));
|
|
$this->assertTrue(isset($rows[0]['customer_id']));
|
|
$this->assertTrue(isset($rows[0]['total']));
|
|
|
|
$db->slavePdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_UPPER);
|
|
$rows = $db->createCommand($sql)->queryAll();
|
|
$this->assertTrue(isset($rows[0]));
|
|
$this->assertTrue(isset($rows[0]['CUSTOMER_ID']));
|
|
$this->assertTrue(isset($rows[0]['TOTAL']));
|
|
}
|
|
}
|