Fix MSSQL tests (#17426)

This commit is contained in:
Alexander Kartavenko
2019-07-11 19:39:46 +03:00
committed by Alexander Makarov
parent 7e77dd2322
commit d98f4e69b5
7 changed files with 171 additions and 99 deletions

View File

@ -7,7 +7,6 @@
namespace yiiunit\framework\db; namespace yiiunit\framework\db;
use Yii;
use yii\db\BatchQueryResult; use yii\db\BatchQueryResult;
use yii\db\Query; use yii\db\Query;
use yiiunit\data\ar\ActiveRecord; use yiiunit\data\ar\ActiveRecord;
@ -23,10 +22,6 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
public function testQuery() public function testQuery()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$db = $this->getConnection(); $db = $this->getConnection();
// initialize property test // initialize property test
@ -40,20 +35,14 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
// normal query // normal query
$query = new Query(); $query = new Query();
$query->from('customer')->orderBy('id'); $query->from('customer')->orderBy('id');
$allRows = [];
$batch = $query->batch(2, $db); $batch = $query->batch(2, $db);
foreach ($batch as $rows) { $allRows = $this->getAllRowsFromBach($batch);
$allRows = array_merge($allRows, $rows);
}
$this->assertCount(3, $allRows); $this->assertCount(3, $allRows);
$this->assertEquals('user1', $allRows[0]['name']); $this->assertEquals('user1', $allRows[0]['name']);
$this->assertEquals('user2', $allRows[1]['name']); $this->assertEquals('user2', $allRows[1]['name']);
$this->assertEquals('user3', $allRows[2]['name']); $this->assertEquals('user3', $allRows[2]['name']);
// rewind // rewind
$allRows = []; $allRows = $this->getAllRowsFromBach($batch);
foreach ($batch as $rows) {
$allRows = array_merge($allRows, $rows);
}
$this->assertCount(3, $allRows); $this->assertCount(3, $allRows);
// reset // reset
$batch->reset(); $batch->reset();
@ -71,10 +60,7 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
// query with index // query with index
$query = new Query(); $query = new Query();
$query->from('customer')->indexBy('name'); $query->from('customer')->indexBy('name');
$allRows = []; $allRows = $this->getAllRowsFromBach($query->batch(2, $db));
foreach ($query->batch(2, $db) as $rows) {
$allRows = array_merge($allRows, $rows);
}
$this->assertCount(3, $allRows); $this->assertCount(3, $allRows);
$this->assertEquals('address1', $allRows['user1']['address']); $this->assertEquals('address1', $allRows['user1']['address']);
$this->assertEquals('address2', $allRows['user2']['address']); $this->assertEquals('address2', $allRows['user2']['address']);
@ -83,10 +69,7 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
// each // each
$query = new Query(); $query = new Query();
$query->from('customer')->orderBy('id'); $query->from('customer')->orderBy('id');
$allRows = []; $allRows = $this->getAllRowsFromEach($query->each(2, $db));
foreach ($query->each(2, $db) as $index => $row) {
$allRows[$index] = $row;
}
$this->assertCount(3, $allRows); $this->assertCount(3, $allRows);
$this->assertEquals('user1', $allRows[0]['name']); $this->assertEquals('user1', $allRows[0]['name']);
$this->assertEquals('user2', $allRows[1]['name']); $this->assertEquals('user2', $allRows[1]['name']);
@ -95,10 +78,7 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
// each with key // each with key
$query = new Query(); $query = new Query();
$query->from('customer')->orderBy('id')->indexBy('name'); $query->from('customer')->orderBy('id')->indexBy('name');
$allRows = []; $allRows = $this->getAllRowsFromEach($query->each(100, $db));
foreach ($query->each(100, $db) as $key => $row) {
$allRows[$key] = $row;
}
$this->assertCount(3, $allRows); $this->assertCount(3, $allRows);
$this->assertEquals('address1', $allRows['user1']['address']); $this->assertEquals('address1', $allRows['user1']['address']);
$this->assertEquals('address2', $allRows['user2']['address']); $this->assertEquals('address2', $allRows['user2']['address']);
@ -107,17 +87,10 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
public function testActiveQuery() public function testActiveQuery()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$db = $this->getConnection(); $db = $this->getConnection();
$query = Customer::find()->orderBy('id'); $query = Customer::find()->orderBy('id');
$customers = []; $customers = $this->getAllRowsFromBach($query->batch(2, $db));
foreach ($query->batch(2, $db) as $models) {
$customers = array_merge($customers, $models);
}
$this->assertCount(3, $customers); $this->assertCount(3, $customers);
$this->assertEquals('user1', $customers[0]->name); $this->assertEquals('user1', $customers[0]->name);
$this->assertEquals('user2', $customers[1]->name); $this->assertEquals('user2', $customers[1]->name);
@ -125,16 +98,33 @@ abstract class BatchQueryResultTest extends DatabaseTestCase
// batch with eager loading // batch with eager loading
$query = Customer::find()->with('orders')->orderBy('id'); $query = Customer::find()->with('orders')->orderBy('id');
$customers = []; $customers = $this->getAllRowsFromBach($query->batch(2, $db));
foreach ($query->batch(2, $db) as $models) { foreach ($customers as $customer) {
$customers = array_merge($customers, $models); $this->assertTrue($customer->isRelationPopulated('orders'));
foreach ($models as $model) {
$this->assertTrue($model->isRelationPopulated('orders'));
}
} }
$this->assertCount(3, $customers); $this->assertCount(3, $customers);
$this->assertCount(1, $customers[0]->orders); $this->assertCount(1, $customers[0]->orders);
$this->assertCount(2, $customers[1]->orders); $this->assertCount(2, $customers[1]->orders);
$this->assertCount(0, $customers[2]->orders); $this->assertCount(0, $customers[2]->orders);
} }
protected function getAllRowsFromBach(BatchQueryResult $batch)
{
$allRows = [];
foreach ($batch as $rows) {
$allRows = array_merge($allRows, $rows);
}
return $allRows;
}
protected function getAllRowsFromEach(BatchQueryResult $each)
{
$allRows = [];
foreach ($each as $index => $row) {
$allRows[$index] = $row;
}
return $allRows;
}
} }

View File

@ -13,7 +13,6 @@ use yii\db\Connection;
use yii\db\DataReader; use yii\db\DataReader;
use yii\db\Exception; use yii\db\Exception;
use yii\db\Expression; use yii\db\Expression;
use yii\db\JsonExpression;
use yii\db\Query; use yii\db\Query;
use yii\db\Schema; use yii\db\Schema;
@ -218,7 +217,7 @@ SQL;
} }
$this->assertEquals($numericCol, $row['numeric_col']); $this->assertEquals($numericCol, $row['numeric_col']);
if ($this->driverName === 'mysql' || $this->driverName === 'oci' || (\defined('HHVM_VERSION') && \in_array($this->driverName, ['sqlite', 'pgsql']))) { if ($this->driverName === 'mysql' || $this->driverName === 'oci' || (\defined('HHVM_VERSION') && \in_array($this->driverName, ['sqlite', 'pgsql']))) {
$this->assertEquals($boolCol, (int) $row['bool_col']); $this->assertEquals($boolCol, (int)$row['bool_col']);
} else { } else {
$this->assertEquals($boolCol, $row['bool_col']); $this->assertEquals($boolCol, $row['bool_col']);
} }
@ -237,7 +236,7 @@ SQL;
public function paramsNonWhereProvider() public function paramsNonWhereProvider()
{ {
return[ return [
['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email GROUP BY SUBSTR(name, :len)'], ['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email GROUP BY SUBSTR(name, :len)'],
['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email ORDER BY SUBSTR(name, :len)'], ['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email ORDER BY SUBSTR(name, :len)'],
['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email'], ['SELECT SUBSTR(name, :len) FROM {{customer}} WHERE [[email]] = :email'],
@ -428,10 +427,6 @@ SQL;
*/ */
public function testBatchInsertSQL($table, $columns, $values, $expected, array $expectedParams = []) public function testBatchInsertSQL($table, $columns, $values, $expected, array $expectedParams = [])
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$command = $this->getConnection()->createCommand(); $command = $this->getConnection()->createCommand();
$command->batchInsert($table, $columns, $values); $command->batchInsert($table, $columns, $values);
$command->prepare(false); $command->prepare(false);
@ -467,22 +462,22 @@ SQL;
*/ */
public function testNoTablenameReplacement() public function testNoTablenameReplacement()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$db = $this->getConnection(); $db = $this->getConnection();
$db->createCommand()->insert( $db->createCommand()->insert(
'{{customer}}', '{{customer}}',
[ [
'id' => 43,
'name' => 'Some {{weird}} name', 'name' => 'Some {{weird}} name',
'email' => 'test@example.com', 'email' => 'test@example.com',
'address' => 'Some {{%weird}} address', 'address' => 'Some {{%weird}} address',
] ]
)->execute(); )->execute();
$customer = $db->createCommand('SELECT * FROM {{customer}} WHERE id=43')->queryOne(); if ($this->driverName === 'pgsql') {
$customerId = $db->getLastInsertID('public.customer_id_seq');
} else {
$customerId = $db->getLastInsertID();
}
$customer = $db->createCommand('SELECT * FROM {{customer}} WHERE id=' . $customerId)->queryOne();
$this->assertEquals('Some {{weird}} name', $customer['name']); $this->assertEquals('Some {{weird}} name', $customer['name']);
$this->assertEquals('Some {{%weird}} address', $customer['address']); $this->assertEquals('Some {{%weird}} address', $customer['address']);
@ -492,9 +487,9 @@ SQL;
'name' => 'Some {{updated}} name', 'name' => 'Some {{updated}} name',
'address' => 'Some {{%updated}} address', 'address' => 'Some {{%updated}} address',
], ],
['id' => 43] ['id' => $customerId]
)->execute(); )->execute();
$customer = $db->createCommand('SELECT * FROM {{customer}} WHERE id=43')->queryOne(); $customer = $db->createCommand('SELECT * FROM {{customer}} WHERE id=' . $customerId)->queryOne();
$this->assertEquals('Some {{updated}} name', $customer['name']); $this->assertEquals('Some {{updated}} name', $customer['name']);
$this->assertEquals('Some {{%updated}} address', $customer['address']); $this->assertEquals('Some {{%updated}} address', $customer['address']);
} }
@ -519,10 +514,10 @@ SQL;
$query = new \yii\db\Query(); $query = new \yii\db\Query();
$query->select([ $query->select([
'{{customer}}.[[email]] as name', '{{customer}}.[[email]] as name',
'[[name]] as email', '[[name]] as email',
'[[address]]', '[[address]]',
] ]
) )
->from('{{customer}}') ->from('{{customer}}')
->where([ ->where([
@ -649,14 +644,14 @@ SQL;
switch ($this->driverName) { switch ($this->driverName) {
case 'pgsql': case 'pgsql':
$expression = "EXTRACT(YEAR FROM TIMESTAMP 'now')"; $expression = "EXTRACT(YEAR FROM TIMESTAMP 'now')";
break; break;
case 'cubrid': case 'cubrid':
case 'mysql': case 'mysql':
$expression = 'YEAR(NOW())'; $expression = 'YEAR(NOW())';
break; break;
case 'sqlite': case 'sqlite':
$expression = "strftime('%Y')"; $expression = "strftime('%Y')";
break; break;
case 'sqlsrv': case 'sqlsrv':
$expression = 'YEAR(GETDATE())'; $expression = 'YEAR(GETDATE())';
} }
@ -678,10 +673,6 @@ SQL;
public function testsInsertQueryAsColumnValue() public function testsInsertQueryAsColumnValue()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$time = time(); $time = time();
$db = $this->getConnection(); $db = $this->getConnection();
@ -689,29 +680,33 @@ SQL;
$command = $db->createCommand(); $command = $db->createCommand();
$command->insert('{{order}}', [ $command->insert('{{order}}', [
'id' => 42,
'customer_id' => 1, 'customer_id' => 1,
'created_at' => $time, 'created_at' => $time,
'total' => 42, 'total' => 42,
])->execute(); ])->execute();
if ($this->driverName === 'pgsql') {
$orderId = $db->getLastInsertID('public.order_id_seq');
} else {
$orderId = $db->getLastInsertID();
}
$columnValueQuery = new \yii\db\Query(); $columnValueQuery = new \yii\db\Query();
$columnValueQuery->select('created_at')->from('{{order}}')->where(['id' => '42']); $columnValueQuery->select('created_at')->from('{{order}}')->where(['id' => $orderId]);
$command = $db->createCommand(); $command = $db->createCommand();
$command->insert( $command->insert(
'{{order_with_null_fk}}', '{{order_with_null_fk}}',
[ [
'customer_id' => 42, 'customer_id' => $orderId,
'created_at' => $columnValueQuery, 'created_at' => $columnValueQuery,
'total' => 42, 'total' => 42,
] ]
)->execute(); )->execute();
$this->assertEquals($time, $db->createCommand('SELECT [[created_at]] FROM {{order_with_null_fk}} WHERE [[customer_id]] = 42')->queryScalar()); $this->assertEquals($time, $db->createCommand('SELECT [[created_at]] FROM {{order_with_null_fk}} WHERE [[customer_id]] = ' . $orderId)->queryScalar());
$db->createCommand('DELETE FROM {{order_with_null_fk}}')->execute(); $db->createCommand('DELETE FROM {{order_with_null_fk}}')->execute();
$db->createCommand('DELETE FROM {{order}} WHERE [[id]] = 42')->execute(); $db->createCommand('DELETE FROM {{order}} WHERE [[id]] = ' . $orderId)->execute();
} }
public function testCreateTable() public function testCreateTable()
@ -1386,6 +1381,8 @@ SQL;
public function testAutoRefreshTableSchema() public function testAutoRefreshTableSchema()
{ {
if ($this->driverName === 'sqlsrv') { if ($this->driverName === 'sqlsrv') {
// related to https://github.com/yiisoft/yii2/pull/17364
$this->markTestSkipped('Should be fixed'); $this->markTestSkipped('Should be fixed');
} }

View File

@ -120,6 +120,7 @@ abstract class QueryTest extends DatabaseTestCase
} }
use GetTablesAliasTestTrait; use GetTablesAliasTestTrait;
protected function createQuery() protected function createQuery()
{ {
return new Query(); return new Query();
@ -338,13 +339,9 @@ abstract class QueryTest extends DatabaseTestCase
public function testUnion() public function testUnion()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$connection = $this->getConnection(); $connection = $this->getConnection();
$query = new Query(); $query = (new Query())
$query->select(['id', 'name']) ->select(['id', 'name'])
->from('item') ->from('item')
->limit(2) ->limit(2)
->union( ->union(
@ -445,10 +442,6 @@ abstract class QueryTest extends DatabaseTestCase
public function testCount() public function testCount()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$db = $this->getConnection(); $db = $this->getConnection();
$count = (new Query())->from('customer')->count('*', $db); $count = (new Query())->from('customer')->count('*', $db);
@ -457,7 +450,7 @@ abstract class QueryTest extends DatabaseTestCase
$count = (new Query())->from('customer')->where(['status' => 2])->count('*', $db); $count = (new Query())->from('customer')->where(['status' => 2])->count('*', $db);
$this->assertEquals(1, $count); $this->assertEquals(1, $count);
$count = (new Query())->select('[[status]], COUNT([[id]])')->from('customer')->groupBy('status')->count('*', $db); $count = (new Query())->select('[[status]], COUNT([[id]]) cnt')->from('customer')->groupBy('status')->count('*', $db);
$this->assertEquals(2, $count); $this->assertEquals(2, $count);
// testing that orderBy() should be ignored here as it does not affect the count anyway. // testing that orderBy() should be ignored here as it does not affect the count anyway.
@ -605,7 +598,7 @@ abstract class QueryTest extends DatabaseTestCase
->where($whereCondition) ->where($whereCondition)
->count('*', $db); ->count('*', $db);
if (is_numeric($result)) { if (is_numeric($result)) {
$result = (int) $result; $result = (int)$result;
} }
return $result; return $result;

View File

@ -7,6 +7,8 @@
namespace yiiunit\framework\db\mssql; namespace yiiunit\framework\db\mssql;
use yii\db\BatchQueryResult;
/** /**
* @group db * @group db
* @group mssql * @group mssql
@ -14,4 +16,37 @@ namespace yiiunit\framework\db\mssql;
class BatchQueryResultTest extends \yiiunit\framework\db\BatchQueryResultTest class BatchQueryResultTest extends \yiiunit\framework\db\BatchQueryResultTest
{ {
public $driverName = 'sqlsrv'; public $driverName = 'sqlsrv';
private $noMoreRowsErrorMessage = 'SQLSTATE[IMSSP]: There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.';
protected function getAllRowsFromBach(BatchQueryResult $batch)
{
$allRows = [];
try {
foreach ($batch as $rows) {
$allRows = array_merge($allRows, $rows);
}
} catch (\PDOException $e) {
if ($e->getMessage() !== $this->noMoreRowsErrorMessage) {
throw $e;
}
}
return $allRows;
}
protected function getAllRowsFromEach(BatchQueryResult $each)
{
$allRows = [];
try {
foreach ($each as $index => $row) {
$allRows[$index] = $row;
}
} catch (\PDOException $e) {
if ($e->getMessage() !== $this->noMoreRowsErrorMessage) {
throw $e;
}
}
return $allRows;
}
} }

View File

@ -121,7 +121,9 @@ class CommandTest extends \yiiunit\framework\db\CommandTest
{ {
$data = parent::batchInsertSqlProvider(); $data = parent::batchInsertSqlProvider();
$data['issue11242']['expected'] = 'INSERT INTO [type] ([int_col], [float_col], [char_col]) VALUES (NULL, NULL, \'Kyiv {{city}}, Ukraine\')'; $data['issue11242']['expected'] = 'INSERT INTO [type] ([int_col], [float_col], [char_col]) VALUES (NULL, NULL, \'Kyiv {{city}}, Ukraine\')';
$data['wrongBehavior']['expected'] = 'INSERT INTO [type] ([int_col], [float_col], [char_col]) VALUES (\'\', \'\', \'Kyiv {{city}}, Ukraine\')'; $data['wrongBehavior']['expected'] = 'INSERT INTO [type] ([type].[int_col], [float_col], [char_col]) VALUES (\'\', \'\', \'Kyiv {{city}}, Ukraine\')';
$data['batchInsert binds params from expression']['expected'] = 'INSERT INTO [type] ([int_col]) VALUES (:qp1)';
unset($data['batchIsert empty rows represented by ArrayObject']);
return $data; return $data;
} }

View File

@ -7,6 +7,8 @@
namespace yiiunit\framework\db\mssql; namespace yiiunit\framework\db\mssql;
use yii\db\Query;
/** /**
* @group db * @group db
* @group mssql * @group mssql
@ -14,4 +16,33 @@ namespace yiiunit\framework\db\mssql;
class QueryTest extends \yiiunit\framework\db\QueryTest class QueryTest extends \yiiunit\framework\db\QueryTest
{ {
protected $driverName = 'sqlsrv'; protected $driverName = 'sqlsrv';
public function testUnion()
{
$connection = $this->getConnection();
// MSSQL supports limit only in sub queries with UNION
$query = (new Query())
->select(['id', 'name'])
->from(
(new Query())
->select(['id', 'name'])
->from('item')
->limit(2)
)
->union(
(new Query())
->select(['id', 'name'])
->from(
(new Query())
->select(['id', 'name'])
->from(['category'])
->limit(2)
)
);
$result = $query->all($connection);
$this->assertNotEmpty($result);
$this->assertCount(4, $result);
}
} }

View File

@ -16,6 +16,28 @@ use yiiunit\framework\db\DatabaseTestCase;
class ProfileFixture extends ActiveFixture class ProfileFixture extends ActiveFixture
{ {
public $modelClass = 'yiiunit\data\ar\Profile'; public $modelClass = 'yiiunit\data\ar\Profile';
public function beforeLoad()
{
if ($this->db->driverName === 'sqlsrv') {
$this->db->createCommand()->truncateTable('profile')->execute();
}
parent::beforeLoad();
}
protected function getData()
{
$data = parent::getData();
if ($this->db->driverName === 'sqlsrv') {
array_walk($data, static function (&$item) {
unset($item['id']);
});
}
return $data;
}
} }
class CustomerFixture extends ActiveFixture class CustomerFixture extends ActiveFixture
@ -25,6 +47,15 @@ class CustomerFixture extends ActiveFixture
public $depends = [ public $depends = [
'yiiunit\framework\test\ProfileFixture', 'yiiunit\framework\test\ProfileFixture',
]; ];
public function beforeLoad()
{
if ($this->db->driverName === 'sqlsrv') {
$this->db->createCommand()->truncateTable('customer')->execute();
}
parent::beforeLoad();
}
} }
class CustomDirectoryFixture extends ActiveFixture class CustomDirectoryFixture extends ActiveFixture
@ -32,6 +63,15 @@ class CustomDirectoryFixture extends ActiveFixture
public $modelClass = 'yiiunit\data\ar\Customer'; public $modelClass = 'yiiunit\data\ar\Customer';
public $dataDirectory = '@app/framework/test/custom'; public $dataDirectory = '@app/framework/test/custom';
public function beforeLoad()
{
if ($this->db->driverName === 'sqlsrv') {
$this->db->createCommand()->truncateTable('customer')->execute();
}
parent::beforeLoad();
}
} }
class AnimalFixture extends ActiveFixture class AnimalFixture extends ActiveFixture
@ -122,10 +162,6 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testGetData() public function testGetData()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$test = new CustomerDbTestCase(); $test = new CustomerDbTestCase();
$test->setUp(); $test->setUp();
$fixture = $test->getFixture('customers'); $fixture = $test->getFixture('customers');
@ -145,10 +181,6 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testGetModel() public function testGetModel()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$test = new CustomerDbTestCase(); $test = new CustomerDbTestCase();
$test->setUp(); $test->setUp();
$fixture = $test->getFixture('customers'); $fixture = $test->getFixture('customers');
@ -167,10 +199,6 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testDataDirectory() public function testDataDirectory()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$test = new CustomDirectoryDbTestCase(); $test = new CustomDirectoryDbTestCase();
$test->setUp(); $test->setUp();
@ -185,10 +213,6 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testDataPath() public function testDataPath()
{ {
if ($this->driverName === 'sqlsrv') {
$this->markTestSkipped('Should be fixed');
}
$test = new DataPathDbTestCase(); $test = new DataPathDbTestCase();
$test->setUp(); $test->setUp();