2010-10-13 06:06:50 +02:00
|
|
|
<?php
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2016-10-14 03:30:05 +02:00
|
|
|
namespace SilverStripe\ORM\Tests;
|
|
|
|
|
|
|
|
use SilverStripe\ORM\Connect\MySQLQuery;
|
|
|
|
use SilverStripe\ORM\Connect\MySQLStatement;
|
2016-06-15 06:03:16 +02:00
|
|
|
use SilverStripe\ORM\DB;
|
|
|
|
use SilverStripe\ORM\Connect\MySQLiConnector;
|
|
|
|
use SilverStripe\ORM\Queries\SQLUpdate;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Dev\SapphireTest;
|
2023-10-02 04:25:14 +02:00
|
|
|
use SilverStripe\ORM\Connect\MySQLDatabase;
|
|
|
|
use SilverStripe\ORM\Tests\MySQLSchemaManagerTest\MySQLDBDummy;
|
2010-10-13 06:06:50 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
class MySQLDatabaseTest extends SapphireTest
|
|
|
|
{
|
|
|
|
|
|
|
|
protected static $fixture_file = 'MySQLDatabaseTest.yml';
|
|
|
|
|
2020-04-20 19:58:09 +02:00
|
|
|
protected static $extra_dataobjects = [
|
2016-12-16 05:34:21 +01:00
|
|
|
MySQLDatabaseTest\Data::class
|
2020-04-20 19:58:09 +02:00
|
|
|
];
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
public function testPreparedStatements()
|
|
|
|
{
|
|
|
|
if (!(DB::get_connector() instanceof MySQLiConnector)) {
|
|
|
|
$this->markTestSkipped('This test requires the current DB connector is MySQLi');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test preparation of equivalent statemetns
|
|
|
|
$result1 = DB::get_connector()->preparedQuery(
|
|
|
|
'SELECT "Sort", "Title" FROM "MySQLDatabaseTest_Data" WHERE "Sort" > ? ORDER BY "Sort"',
|
2020-04-20 19:58:09 +02:00
|
|
|
[0]
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$result2 = DB::get_connector()->preparedQuery(
|
|
|
|
'SELECT "Sort", "Title" FROM "MySQLDatabaseTest_Data" WHERE "Sort" > ? ORDER BY "Sort"',
|
2020-04-20 19:58:09 +02:00
|
|
|
[2]
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertInstanceOf(MySQLStatement::class, $result1);
|
|
|
|
$this->assertInstanceOf(MySQLStatement::class, $result2);
|
|
|
|
|
|
|
|
// Also select non-prepared statement
|
|
|
|
$result3 = DB::get_connector()->query('SELECT "Sort", "Title" FROM "MySQLDatabaseTest_Data" ORDER BY "Sort"');
|
|
|
|
$this->assertInstanceOf(MySQLQuery::class, $result3);
|
|
|
|
|
|
|
|
// Iterating one level should not buffer, but return the right result
|
2017-06-28 13:22:45 +02:00
|
|
|
$result1Array = [];
|
2017-06-28 16:21:53 +02:00
|
|
|
foreach ($result1 as $record) {
|
2017-06-28 13:22:45 +02:00
|
|
|
$result1Array[] = $record;
|
|
|
|
}
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2020-04-20 19:58:09 +02:00
|
|
|
[
|
2017-06-28 13:22:45 +02:00
|
|
|
[ 'Sort' => 1, 'Title' => 'First Item' ],
|
|
|
|
[ 'Sort' => 2, 'Title' => 'Second Item' ],
|
|
|
|
[ 'Sort' => 3, 'Title' => 'Third Item' ],
|
|
|
|
[ 'Sort' => 4, 'Title' => 'Last Item' ],
|
2022-09-02 00:58:37 +02:00
|
|
|
],
|
2017-06-28 13:22:45 +02:00
|
|
|
$result1Array
|
2022-09-02 00:58:37 +02:00
|
|
|
);
|
|
|
|
|
2017-06-28 13:22:45 +02:00
|
|
|
// Test count
|
|
|
|
$this->assertEquals(4, $result1->numRecords());
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
// Test count
|
|
|
|
$this->assertEquals(4, $result1->numRecords());
|
|
|
|
|
|
|
|
// Test second statement
|
2017-06-28 13:22:45 +02:00
|
|
|
$result2Array = [];
|
2017-06-28 16:21:53 +02:00
|
|
|
foreach ($result2 as $record) {
|
2017-06-28 13:22:45 +02:00
|
|
|
$result2Array[] = $record;
|
|
|
|
break;
|
|
|
|
}
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2020-04-20 19:58:09 +02:00
|
|
|
[
|
2017-06-28 13:22:45 +02:00
|
|
|
[ 'Sort' => 3, 'Title' => 'Third Item' ],
|
2020-04-20 19:58:09 +02:00
|
|
|
],
|
2017-06-28 13:22:45 +02:00
|
|
|
$result2Array
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
// Test non-prepared query
|
2017-06-28 13:22:45 +02:00
|
|
|
$result3Array = [];
|
2017-06-28 16:21:53 +02:00
|
|
|
foreach ($result3 as $record) {
|
2017-06-28 13:22:45 +02:00
|
|
|
$result3Array[] = $record;
|
|
|
|
break;
|
|
|
|
}
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2020-04-20 19:58:09 +02:00
|
|
|
[
|
2017-06-28 13:22:45 +02:00
|
|
|
[ 'Sort' => 1, 'Title' => 'First Item' ],
|
2020-04-20 19:58:09 +02:00
|
|
|
],
|
2017-06-28 13:22:45 +02:00
|
|
|
$result3Array
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testAffectedRows()
|
|
|
|
{
|
|
|
|
if (!(DB::get_connector() instanceof MySQLiConnector)) {
|
|
|
|
$this->markTestSkipped('This test requires the current DB connector is MySQLi');
|
|
|
|
}
|
|
|
|
|
|
|
|
$query = new SQLUpdate('MySQLDatabaseTest_Data');
|
2020-04-20 19:58:09 +02:00
|
|
|
$query->setAssignments(['Title' => 'New Title']);
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
// Test update which affects no rows
|
2020-04-20 19:58:09 +02:00
|
|
|
$query->setWhere(['Title' => 'Bob']);
|
2016-12-16 05:34:21 +01:00
|
|
|
$result = $query->execute();
|
|
|
|
$this->assertInstanceOf(MySQLQuery::class, $result);
|
|
|
|
$this->assertEquals(0, DB::affected_rows());
|
|
|
|
|
|
|
|
// Test update which affects some rows
|
2020-04-20 19:58:09 +02:00
|
|
|
$query->setWhere(['Title' => 'First Item']);
|
2016-12-16 05:34:21 +01:00
|
|
|
$result = $query->execute();
|
|
|
|
$this->assertInstanceOf(MySQLQuery::class, $result);
|
|
|
|
$this->assertEquals(1, DB::affected_rows());
|
|
|
|
}
|
2023-10-02 04:25:14 +02:00
|
|
|
|
|
|
|
public function provideSupportsCte()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
// mysql unsupported
|
|
|
|
[
|
|
|
|
'version' => '1.1.1',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '5.9999.9999',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '8.0.0',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
// mysql supported
|
|
|
|
[
|
|
|
|
'version' => '8.0.1',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.0',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '999.999.999',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
// mariaDB unsupported (various formats)
|
|
|
|
[
|
|
|
|
'version' => '5.5.5-10.2.0-mariadb-1:10.6.8+maria~focal',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.0-mariadb-1:10.6.8+maria~jammy',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.0-mariadb-1:10.2.0+maria~focal',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
// mariadb supported (various formats)
|
|
|
|
[
|
|
|
|
'version' => '5.5.5-10.2.1-mariadb-1:10.6.8+maria~focal',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.1-mariadb-1:10.6.8+maria~jammy',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.1-mariadb-1:10.2.1+maria~focal',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '10.2.2-mariadb-1:10.2.2+maria~jammy',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '5.5.5-10.2.2-mariadb-1:10.2.2+maria~jammy',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'version' => '5.5.5-999.999.999-mariadb-1:10.2.2+maria~jammy',
|
|
|
|
'expected' => true,
|
|
|
|
'expectedRecursive' => true,
|
|
|
|
],
|
|
|
|
// completely invalid versions
|
|
|
|
[
|
|
|
|
'version' => '999.999.999-some-random-string',
|
|
|
|
'expected' => false,
|
|
|
|
'expectedRecursive' => false,
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideSupportsCte
|
|
|
|
*/
|
|
|
|
public function testSupportsCte(string $version, bool $expected, bool $expectedRecursive)
|
|
|
|
{
|
|
|
|
$database = new MySQLDBDummy($version);
|
|
|
|
$this->assertSame($expected, $database->supportsCteQueries());
|
|
|
|
$this->assertSame($expectedRecursive, $database->supportsCteQueries(true));
|
|
|
|
}
|
2010-10-13 06:06:50 +02:00
|
|
|
}
|