View source
<?php
namespace Drupal\Tests\sqlsrv\Kernel;
use Drupal\Core\Database\Database;
use Drupal\Driver\Database\sqlsrv\Condition;
use Drupal\Driver\Database\sqlsrv\Connection;
use Drupal\KernelTests\Core\Database\DatabaseTestBase;
class SqlsrvTest extends DatabaseTestBase {
public function testParameterLimit() {
$values = [];
for ($x = 0; $x < 2200; $x++) {
$values[] = uniqid(strval($x), TRUE);
}
$query = $this->connection
->select('test_task', 't');
$query
->addExpression('COUNT(task)', 'num');
$query
->where('t.task IN (:data)', [
':data' => $values,
]);
$result = NULL;
try {
$result = $query
->execute()
->fetchField();
} catch (\Exception $err) {
}
$this
->assertEqual($result, 0, 'Returned the correct number of total rows.');
}
public function testDuplicatePlaceholders() {
$query = $this->connection
->select('test_task', 't');
$query
->addExpression('COUNT(task)', 'num');
$query
->where('t.task IN (:data0, :data0)', [
':data0' => 'sleep',
]);
$result = NULL;
try {
$result = $query
->execute()
->fetchField();
} catch (\Exception $err) {
}
$this
->assertEqual($result, 2, 'Returned the correct number of total rows.');
}
public function testTemporaryTables($temp_prefix, $leak_table) {
$reflectionClass = new \ReflectionClass(Connection::class);
$reflectionProperty = $reflectionClass
->getProperty('tempTablePrefix');
$reflectionProperty
->setAccessible(TRUE);
$reflectionProperty
->setValue($this->connection, $temp_prefix);
$reflectionMethod = $reflectionClass
->getMethod('setPrefix');
$reflectionMethod
->setAccessible(TRUE);
$prefixProperty = $reflectionClass
->getProperty('prefixes');
$prefixProperty
->setAccessible(TRUE);
$prefixes = $prefixProperty
->getValue($this->connection);
$reflectionMethod
->invoke($this->connection, $prefixes);
$query = $this->connection
->select('test_task', 't');
$query
->fields('t');
$table = $this->connection
->queryTemporary((string) $query);
$this
->assertTRUE($this->connection
->schema()
->tableExists($table), 'The temporary table exists.');
$query2 = $this->connection
->select($table, 't');
$query2
->fields('t');
$data1 = $query
->execute()
->fetchAllAssoc('tid');
$data2 = $query2
->execute()
->fetchAllAssoc('tid');
$this
->assertEqual(count($data1), count($data2), 'Temporary table has the same number of rows.');
$this->connection
->schema()
->dropTable($table);
$this
->assertFALSE($this->connection
->schema()
->tableExists($table), 'The temporary table does not exist');
$schema = [
'description' => 'Basic test table for the database unit tests.',
'fields' => [
'id' => [
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
],
];
$connection_info = $this
->getDatabaseConnectionInfo()['default'];
Database::addConnectionInfo('second', 'second', $connection_info);
Database::addConnectionInfo('third', 'third', $connection_info);
$second_connection = Database::getConnection('second', 'second');
$reflectionProperty
->setValue($second_connection, $temp_prefix);
$prefixes = $prefixProperty
->getValue($second_connection);
$reflectionMethod
->invoke($second_connection, $prefixes);
$third_connection = Database::getConnection('third', 'third');
$reflectionProperty
->setValue($third_connection, $temp_prefix);
$prefixes = $prefixProperty
->getValue($third_connection);
$reflectionMethod
->invoke($third_connection, $prefixes);
$connection_id1 = $this->connection
->query('SELECT @@SPID AS [ID]')
->fetchField();
$connection_id2 = $second_connection
->query('SELECT @@SPID AS [ID]')
->fetchField();
$connection_id3 = $third_connection
->query('SELECT @@SPID AS [ID]')
->fetchField();
$this
->assertNotEquals($connection_id2, $connection_id3, 'Connections 2 & 3 have different IDs.');
$this
->assertNotEquals($connection_id1, $connection_id3, 'Connections 1 & 3 have different IDs.');
$this
->assertNotEquals($connection_id2, $connection_id1, 'Connections 1 & 2 have different IDs.');
$table = $second_connection
->queryTemporary((string) $query);
$this
->assertTrue($second_connection
->schema()
->tableExists($table), 'Temporary table exists.');
$second_connection
->schema()
->createTable('real_table_for_temp_test', $schema);
$this
->assertTrue($third_connection
->schema()
->tableExists('real_table_for_temp_test'), 'Real table found across connections.');
$this
->assertEquals($leak_table, $third_connection
->schema()
->tableExists($table), 'Temporary table leaking appropriately.');
$this
->assertTrue($second_connection
->schema()
->tableExists($table), 'Temporary table still exists.');
unset($second_connection);
Database::removeConnection('second');
sleep(2);
$this
->assertFalse($third_connection
->schema()
->tableExists($table), 'Temporary table removed when creation connection closes.');
}
public function dataProviderForTestTemporaryTables() {
return [
'local' => [
'#',
FALSE,
],
'global' => [
'##',
TRUE,
],
];
}
public function testEscapeLike() {
$string = 't[e%s]t_\\';
$escaped_string = $this->connection
->escapeLike($string);
$this
->assertEqual($escaped_string, 't[e\\%s]t\\_\\\\', 'Properly escaped string with backslashes');
$query = $this->connection
->select('test_task', 't');
$condition = new Condition('AND');
$condition
->condition('task', $escaped_string, 'LIKE');
$condition
->compile($this->connection, $query);
$arguments = $condition
->conditions();
$argument = $arguments[0];
$expected = 't[[]e[%]s]t[_]\\';
$actual = $argument['value'];
$this
->assertEqual($actual, $expected, 'Properly escaped LIKE statement wildcards.');
$this->connection
->insert('test_task')
->fields([
'task' => 'T\\est',
])
->execute();
$query = $this->connection
->select('test_task', 't');
$query
->fields('t');
$query
->condition('t.task', $this->connection
->escapeLike('T\\est'), 'LIKE');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 1, t('db_select returned the correct number of total rows.'));
$this->connection
->insert('test_task')
->fields([
'task' => 'T\'est',
])
->execute();
$query = $this->connection
->select('test_task', 't');
$query
->fields('t');
$query
->condition('t.task', $this->connection
->escapeLike('T\'est'), 'LIKE');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 1, t('db_select returned the correct number of total rows.'));
$query = $this->connection
->select('test_task', 't');
$query
->condition('t.task', '_leep', 'LIKE');
$query
->fields('t');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 2, t('db_select returned the correct number of total rows.'));
$query = $this->connection
->select('test_task', 't');
$query
->condition('t.task', $this->connection
->escapeLike('_leep'), 'LIKE');
$query
->fields('t');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 0, t('db_select returned the correct number of total rows.'));
$query = $this->connection
->select('test_task', 't');
$query
->where('t.task LIKE :task', [
':task' => '[s]leep',
]);
$query
->fields('t');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 2, t('db_select returned the correct number of total rows.'));
$query = $this->connection
->select('test_task', 't');
$query
->where('t.task LIKE :task', [
':task' => $this->connection
->escapeLike('[[]s[]]leep'),
]);
$query
->fields('t');
$result = $query
->execute()
->fetchAll();
$this
->assertEqual(count($result), 0, t('db_select returned the correct number of total rows.'));
$query = $this->connection
->query('SELECT COUNT(*) FROM {test_task} WHERE task LIKE :task', [
':task' => '[s]leep',
]);
$result = $query
->fetchField();
$this
->assertEqual($result, 2, t('db_query returned the correct number of total rows.'));
$query = $this->connection
->query('SELECT COUNT(*) FROM {test_task} WHERE task LIKE :task', [
':task' => $this->connection
->escapeLike('[[]s[]]leep'),
]);
$result = $query
->fetchField();
$this
->assertEqual($result, 0, t('db_query returned the correct number of total rows.'));
}
}