Unverified Commit d3205dcb authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge branch '2.11.x' into 2.10.x-merge-up-into-2.11.x_5e9de30c262e49.66926046

parents aab745e7 50927b6b
/.appveyor.yml export-ignore
/composer.lock export-ignore
/docs export-ignore
/.doctrine-project.json export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.scrutinizer.yml export-ignore
/.travis.yml export-ignore
/build.properties export-ignore
/build.xml export-ignore
/composer.lock export-ignore
/docs export-ignore
/phpcs.xml.dist export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/run-all.sh export-ignore
/.scrutinizer.yml export-ignore
/SECURITY.md export-ignore
/tests export-ignore
/.travis.yml export-ignore
/UPGRADE.md export-ignore
# Upgrade to 2.11
## Deprecated `EchoSQLLogger`
The `EchoSQLLogger` is has been deprecated. Implement your logger with the desired logic.
## Deprecated database platforms:
1. PostgreSQL 9.3 and older
2. MariaDB 10.0 and older
3. SQL Server 2008 and older
4. SQL Anywhere 12 and older
5. Drizzle
6. Azure SQL Database
## Deprecated database drivers:
1. PDO-based IBM DB2 driver
2. Drizzle MySQL driver
## Deprecated `Doctrine\DBAL\Sharding` package
The sharding functionality in DBAL has been effectively unmaintained for a long time.
## Deprecated `Doctrine\DBAL\Version` class
The usage of the `Doctrine\DBAL\Version` class is deprecated as internal implementation detail. Please refrain from checking the DBAL version at runtime.
## Deprecated `ExpressionBuilder` methods
The usage of the `andX()` and `orX()` methods of the `ExpressionBuilder` class has been deprecated. Use `and()` and `or()` instead.
## Deprecated `CompositeExpression` methods
- The usage of the `add()` and `addMultiple()` methods of the `CompositeExpression` class has been deprecated. Use `with()` instead, which returns a new instance.
In the future, the `add*()` methods will be removed and the class will be effectively immutable.
- The usage of the `CompositeExpression` constructor has been deprecated. Use the `and()` / `or()` factory methods.
## Deprecated calling `QueryBuilder` methods with an array argument
Calling the `select()`, `addSelect()`, `groupBy()` and `addGroupBy()` methods with an array argument is deprecated.
# Upgrade to 2.10
## Deprecated `Doctrine\DBAL\Event\ConnectionEventArgs` methods
......
......@@ -50,25 +50,25 @@ Oracle
Microsoft SQL Server
^^^^^^^^^^^^^^^^^^^^
- ``SQLServerPlatform`` for version 2000 and above.
- ``SQLServer2005Platform`` for version 2005 and above.
- ``SQLServer2008Platform`` for version 2008 and above.
- ``SQLServerPlatform`` for version 2000 and above (deprecated).
- ``SQLServer2005Platform`` for version 2005 and above (deprecated).
- ``SQLServer2008Platform`` for version 2008 and above (deprecated).
- ``SQLServer2012Platform`` for version 2012 and above.
PostgreSQL
^^^^^^^^^^
- ``PostgreSqlPlatform`` for all versions.
- ``PostgreSQL91Platform`` for version 9.1 and above.
- ``PostgreSQL92Platform`` for version 9.2 and above.
- ``PostgreSqlPlatform`` for version 9.0 and below (deprecated).
- ``PostgreSQL91Platform`` for version 9.1 and above (deprecated).
- ``PostgreSQL92Platform`` for version 9.2 and above (deprecated).
- ``PostgreSQL94Platform`` for version 9.4 and above.
SAP Sybase SQL Anywhere
^^^^^^^^^^^^^^^^^^^^^^^
- ``SQLAnywherePlatform`` for version 10 and above.
- ``SQLAnywhere11Platform`` for version 11 and above.
- ``SQLAnywhere12Platform`` for version 12 and above.
- ``SQLAnywherePlatform`` for version 10 and above (deprecated).
- ``SQLAnywhere11Platform`` for version 11 and above (deprecated).
- ``SQLAnywhere12Platform`` for version 12 and above (deprecated).
- ``SQLAnywhere16Platform`` for version 16 and above.
SQLite
......@@ -79,7 +79,7 @@ SQLite
Drizzle
^^^^^^
- ``DrizzlePlatform`` for all versions.
- ``DrizzlePlatform`` for all versions (deprecated).
It is highly encouraged to use the platform class that matches your
database vendor and version best. Otherwise it is not guaranteed
......@@ -113,4 +113,3 @@ all the different database vendors, for example MySQL BIGINT and
Oracle NUMBER should be handled as integer. Doctrine 2 offers a
powerful way to abstract the database to php and back conversion,
which is described in the next section.
......@@ -332,13 +332,13 @@ Most notably you can use expressions to build nested And-/Or statements:
->select('id', 'name')
->from('users')
->where(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->and(
$queryBuilder->expr()->eq('username', '?'),
$queryBuilder->expr()->eq('email', '?')
)
);
The ``andX()`` and ``orX()`` methods accept an arbitrary amount
The ``and()`` and ``or()`` methods accept an arbitrary amount
of arguments and can be nested in each other.
There is a bunch of methods to create comparisons and other SQL snippets
......
......@@ -5,6 +5,9 @@ namespace Doctrine\DBAL\Driver\DrizzlePDOMySql;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\ParameterType;
/**
* @deprecated
*/
class Connection extends PDOConnection
{
/**
......
......@@ -7,6 +7,8 @@ use Doctrine\DBAL\Schema\DrizzleSchemaManager;
/**
* Drizzle driver using PDO MySql.
*
* @deprecated
*/
class Driver extends \Doctrine\DBAL\Driver\PDOMySql\Driver
{
......
......@@ -7,6 +7,8 @@ use Doctrine\DBAL\Driver\PDOConnection;
/**
* Driver for the PDO IBM extension.
*
* @deprecated Use the driver based on the ibm_db2 extension instead.
*/
class Driver extends AbstractDB2Driver
{
......
......@@ -7,6 +7,8 @@ use function var_dump;
/**
* A SQL logger that logs to the standard output using echo/var_dump.
*
* @deprecated
*/
class EchoSQLLogger implements SQLLogger
{
......
......@@ -23,6 +23,8 @@ use function trim;
/**
* Drizzle platform
*
* @deprecated
*/
class DrizzlePlatform extends AbstractPlatform
{
......
......@@ -6,6 +6,8 @@ use function explode;
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 9.1 database platform.
*
* @deprecated Use PostgreSQL 9.4 or newer
*/
class PostgreSQL91Platform extends PostgreSqlPlatform
{
......
......@@ -7,6 +7,8 @@ use function sprintf;
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 9.2 database platform.
*
* @deprecated Use PostgreSQL 9.4 or newer
*/
class PostgreSQL92Platform extends PostgreSQL91Platform
{
......
......@@ -35,6 +35,8 @@ use function trim;
/**
* PostgreSqlPlatform.
*
* @deprecated Use PostgreSQL 9.4 or newer
*
* @todo Rename: PostgreSQLPlatform
*/
class PostgreSqlPlatform extends AbstractPlatform
......
......@@ -5,6 +5,8 @@ namespace Doctrine\DBAL\Platforms;
/**
* The SQLAnywhere11Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 11 database platform.
*
* @deprecated Use SQLAnywhere 16 or newer
*/
class SQLAnywhere11Platform extends SQLAnywherePlatform
{
......
......@@ -8,6 +8,8 @@ use Doctrine\DBAL\Schema\Sequence;
/**
* The SQLAnywhere12Platform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 12 database platform.
*
* @deprecated Use SQLAnywhere 16 or newer
*/
class SQLAnywhere12Platform extends SQLAnywhere11Platform
{
......
......@@ -33,6 +33,8 @@ use function substr;
/**
* The SQLAnywherePlatform provides the behavior, features and SQL dialect of the
* SAP Sybase SQL Anywhere 10 database platform.
*
* @deprecated Use SQLAnywhere 16 or newer
*/
class SQLAnywherePlatform extends AbstractPlatform
{
......
......@@ -10,6 +10,8 @@ use Doctrine\DBAL\Schema\Table;
* On top of SQL Server 2008 the following functionality is added:
*
* - Create tables with the FEDERATED ON syntax.
*
* @deprecated
*/
class SQLAzurePlatform extends SQLServer2008Platform
{
......
......@@ -15,6 +15,8 @@ namespace Doctrine\DBAL\Platforms;
* NVARCHAR(max) replace the old TEXT, NTEXT and IMAGE types. See
* {@link http://www.sql-server-helper.com/faq/sql-server-2005-varchar-max-p01.aspx}
* for more information.
*
* @deprecated Use SQL Server 2012 or newer
*/
class SQLServer2005Platform extends SQLServerPlatform
{
......
......@@ -7,6 +7,8 @@ namespace Doctrine\DBAL\Platforms;
*
* Differences to SQL Server 2005 and before are that a new DATETIME2 type was
* introduced that has a higher precision.
*
* @deprecated Use SQL Server 2012 or newer
*/
class SQLServer2008Platform extends SQLServer2005Platform
{
......
......@@ -38,6 +38,8 @@ use function substr_count;
/**
* The SQLServerPlatform provides the behavior, features and SQL dialect of the
* Microsoft SQL Server database platform.
*
* @deprecated Use SQL Server 2012 or newer
*/
class SQLServerPlatform extends AbstractPlatform
{
......
......@@ -3,6 +3,7 @@
namespace Doctrine\DBAL\Query\Expression;
use Countable;
use function array_merge;
use function count;
use function implode;
......@@ -36,6 +37,8 @@ class CompositeExpression implements Countable
private $parts = [];
/**
* @internal Use the and() / or() factory methods.
*
* @param string $type Instance type of composite expression.
* @param self[]|string[] $parts Composition of expressions to be joined on composite expression.
*/
......@@ -46,9 +49,29 @@ class CompositeExpression implements Countable
$this->addMultiple($parts);
}
/**
* @param self|string $part
* @param self|string ...$parts
*/
public static function and($part, ...$parts) : self
{
return new self(self::TYPE_AND, array_merge([$part], $parts));
}
/**
* @param self|string $part
* @param self|string ...$parts
*/
public static function or($part, ...$parts) : self
{
return new self(self::TYPE_OR, array_merge([$part], $parts));
}
/**
* Adds multiple parts to composite expression.
*
* @deprecated This class will be made immutable. Use with() instead.
*
* @param self[]|string[] $parts
*
* @return \Doctrine\DBAL\Query\Expression\CompositeExpression
......@@ -65,6 +88,8 @@ class CompositeExpression implements Countable
/**
* Adds an expression to composite expression.
*
* @deprecated This class will be made immutable. Use with() instead.
*
* @param mixed $part
*
* @return \Doctrine\DBAL\Query\Expression\CompositeExpression
......@@ -84,6 +109,25 @@ class CompositeExpression implements Countable
return $this;
}
/**
* Returns a new CompositeExpression with the given parts added.
*
* @param self|string $part
* @param self|string ...$parts
*/
public function with($part, ...$parts) : self
{
$that = clone $this;
$that->parts[] = $part;
foreach ($parts as $part) {
$that->parts[] = $part;
}
return $that;
}
/**
* Retrieves the amount of expressions on composite expression.
*
......
......@@ -39,13 +39,29 @@ class ExpressionBuilder
}
/**
* Creates a conjunction of the given boolean expressions.
* Creates a conjunction of the given expressions.
*
* Example:
* @param string|CompositeExpression $expression
* @param string|CompositeExpression ...$expressions
*/
public function and($expression, ...$expressions) : CompositeExpression
{
return CompositeExpression::and($expression, ...$expressions);
}
/**
* Creates a disjunction of the given expressions.
*
* [php]
* // (u.type = ?) AND (u.role = ?)
* $expr->andX('u.type = ?', 'u.role = ?'));
* @param string|CompositeExpression $expression
* @param string|CompositeExpression ...$expressions
*/
public function or($expression, ...$expressions) : CompositeExpression
{
return CompositeExpression::or($expression, ...$expressions);
}
/**
* @deprecated Use `and()` instead.
*
* @param mixed $x Optional clause. Defaults = null, but requires
* at least one defined when converting to string.
......@@ -58,13 +74,7 @@ class ExpressionBuilder
}
/**
* Creates a disjunction of the given boolean expressions.
*
* Example:
*
* [php]
* // (u.type = ?) OR (u.role = ?)
* $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?'));
* @deprecated Use `or()` instead.
*
* @param mixed $x Optional clause. Defaults = null, but requires
* at least one defined when converting to string.
......
......@@ -450,6 +450,8 @@ class QueryBuilder
* Specifies an item that is to be returned in the query result.
* Replaces any previously specified selections, if any.
*
* USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument.
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->select('u.id', 'p.id')
......@@ -457,11 +459,12 @@ class QueryBuilder
* ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
* </code>
*
* @param mixed $select The selection expressions.
* @param string|string[]|null $select The selection expression. USING AN ARRAY OR NULL IS DEPRECATED.
* Pass each value as an individual argument.
*
* @return $this This QueryBuilder instance.
*/
public function select($select = null)
public function select($select = null/*, string ...$selects*/)
{
$this->type = self::SELECT;
......@@ -496,6 +499,8 @@ class QueryBuilder
/**
* Adds an item that is to be returned in the query result.
*
* USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument.
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->select('u.id')
......@@ -504,11 +509,12 @@ class QueryBuilder
* ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
* </code>
*
* @param mixed $select The selection expression.
* @param string|string[]|null $select The selection expression. USING AN ARRAY OR NULL IS DEPRECATED.
* Pass each value as an individual argument.
*
* @return $this This QueryBuilder instance.
*/
public function addSelect($select = null)
public function addSelect($select = null/*, string ...$selects*/)
{
$this->type = self::SELECT;
......@@ -792,7 +798,7 @@ class QueryBuilder
public function where($predicates)
{
if (! (func_num_args() === 1 && $predicates instanceof CompositeExpression)) {
$predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
$predicates = CompositeExpression::and(...func_get_args());
}
return $this->add('where', $predicates);
......@@ -822,10 +828,10 @@ class QueryBuilder
$where = $this->getQueryPart('where');
if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) {
$where->addMultiple($args);
$where = $where->with(...$args);
} else {
array_unshift($args, $where);
$where = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
$where = CompositeExpression::and(...$args);
}
return $this->add('where', $where, true);
......@@ -855,10 +861,10 @@ class QueryBuilder
$where = $this->getQueryPart('where');
if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) {
$where->addMultiple($args);
$where = $where->with(...$args);
} else {
array_unshift($args, $where);
$where = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
$where = CompositeExpression::or(...$args);
}
return $this->add('where', $where, true);
......@@ -868,6 +874,8 @@ class QueryBuilder
* Specifies a grouping over the results of the query.
* Replaces any previously specified groupings, if any.
*
* USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument.
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->select('u.name')
......@@ -875,11 +883,12 @@ class QueryBuilder
* ->groupBy('u.id');
* </code>
*
* @param mixed $groupBy The grouping expression.
* @param string|string[] $groupBy The grouping expression. USING AN ARRAY IS DEPRECATED.
* Pass each value as an individual argument.
*
* @return $this This QueryBuilder instance.
*/
public function groupBy($groupBy)
public function groupBy($groupBy/*, string ...$groupBys*/)
{
if (empty($groupBy)) {
return $this;
......@@ -893,6 +902,8 @@ class QueryBuilder
/**
* Adds a grouping expression to the query.
*
* USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument.
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->select('u.name')
......@@ -901,11 +912,12 @@ class QueryBuilder
* ->addGroupBy('u.createdAt');
* </code>
*
* @param mixed $groupBy The grouping expression.
* @param string|string[] $groupBy The grouping expression. USING AN ARRAY IS DEPRECATED.
* Pass each value as an individual argument.
*
* @return $this This QueryBuilder instance.
*/
public function addGroupBy($groupBy)
public function addGroupBy($groupBy/*, string ...$groupBys*/)
{
if (empty($groupBy)) {
return $this;
......@@ -977,7 +989,7 @@ class QueryBuilder
public function having($having)
{
if (! (func_num_args() === 1 && $having instanceof CompositeExpression)) {
$having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
$having = CompositeExpression::and(...func_get_args());
}
return $this->add('having', $having);
......@@ -997,10 +1009,10 @@ class QueryBuilder
$having = $this->getQueryPart('having');
if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) {
$having->addMultiple($args);
$having = $having->with(...$args);
} else {
array_unshift($args, $having);
$having = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
$having = CompositeExpression::and(...$args);
}
return $this->add('having', $having);
......@@ -1020,10 +1032,10 @@ class QueryBuilder
$having = $this->getQueryPart('having');
if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) {
$having->addMultiple($args);
$having = $having->with(...$args);
} else {
array_unshift($args, $having);
$having = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
$having = CompositeExpression::or(...$args);
}
return $this->add('having', $having);
......
......@@ -32,6 +32,8 @@ use function is_string;
*
* Instantiation through the DriverManager looks like:
*
* @deprecated
*
* @example
*
* $conn = DriverManager::getConnection(array(
......
......@@ -7,6 +7,8 @@ use RuntimeException;
/**
* Shard Manager for the Connection Pooling Shard Strategy
*
* @deprecated
*/
class PoolingShardManager implements ShardManager
{
......
......@@ -20,6 +20,8 @@ use function array_merge;
* by partitioning the passed schema into subschemas for the federation and the
* global database and then applying the operations step by step using the
* {@see \Doctrine\DBAL\Schema\Synchronizer\SingleDatabaseSynchronizer}.
*
* @deprecated
*/
class SQLAzureFederationsSynchronizer extends AbstractSchemaSynchronizer
{
......
......@@ -11,6 +11,8 @@ use function sprintf;
/**
* Sharding using the SQL Azure Federations support.
*
* @deprecated
*/
class SQLAzureShardManager implements ShardManager
{
......
......@@ -30,6 +30,8 @@ use function in_array;
* (otherwise they will affect the same-id rows from other tenants as well).
* SQLAzure throws errors when you try to create IDENTIY columns on federated
* tables.
*
* @deprecated
*/
class MultiTenantVisitor implements Visitor
{
......
......@@ -7,6 +7,8 @@ use Doctrine\DBAL\Sharding\PoolingShardConnection;
/**
* The MultiTenant Shard choser assumes that the distribution value directly
* maps to the shard id.
*
* @deprecated
*/
class MultiTenantShardChoser implements ShardChoser
{
......
......@@ -7,6 +7,8 @@ use Doctrine\DBAL\Sharding\PoolingShardConnection;
/**
* Given a distribution value this shard-choser strategy will pick the shard to
* connect to for retrieving rows with the distribution value.
*
* @deprecated
*/
interface ShardChoser
{
......
......@@ -17,6 +17,8 @@ namespace Doctrine\DBAL\Sharding;
* executed against the last shard that was selected. If a query is created for
* a shard Y but then a shard X is selected when its actually executed you
* will hit the wrong shard.
*
* @deprecated
*/
interface ShardManager
{
......
......@@ -7,6 +7,8 @@ use Doctrine\DBAL\DBALException;
/**
* Sharding related Exceptions
*
* @deprecated
*
* @psalm-immutable
*/
class ShardingException extends DBALException
......
......@@ -8,13 +8,16 @@ use function version_compare;
/**
* Class to store and retrieve the version of Doctrine.
*
* @internal
* @deprecated Refrain from checking the DBAL version at runtime.
*/
class Version
{
/**
* Current Doctrine Version.
*/
public const VERSION = '2.10.2';
public const VERSION = '2.11.0-DEV';
/**
* Compares a Doctrine version with the current one.
......
......@@ -44,11 +44,7 @@
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>./tests/Doctrine/Tests/DBAL</directory>
<exclude>./tests/Doctrine/Tests/DBAL/Performance</exclude>
</testsuite>
<testsuite name="Doctrine DBAL Performance Test Suite">
<directory>./tests/Doctrine/Tests/DBAL/Performance</directory>
<directory>tests/Doctrine/Tests/DBAL</directory>
</testsuite>
</testsuites>
......@@ -57,14 +53,4 @@
<directory suffix=".php">lib/Doctrine</directory>
</whitelist>
</filter>
<listeners>
<listener class="Doctrine\Tests\DbalPerformanceTestListener"/>
</listeners>
<groups>
<exclude>
<group>performance</group>
</exclude>
</groups>
</phpunit>
<?php
namespace Doctrine\Tests\DBAL\Performance;
use DateTime;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DbalPerformanceTestCase;
/**
* @group performance
*/
class TypeConversionPerformanceTest extends DbalPerformanceTestCase
{
/**
* @throws DBALException
*
* @dataProvider itemCountProvider
*/
public function testDateTimeTypeConversionPerformance(int $count) : void
{
$value = new DateTime();
$type = Type::getType('datetime');
$platform = $this->connection->getDatabasePlatform();
$this->startTiming();
for ($i = 0; $i < $count; $i++) {
$type->convertToDatabaseValue($value, $platform);
}
$this->stopTiming();
}
/**
* @return mixed[][]
*/
public static function itemCountProvider() : iterable
{
return [
'100 items' => [100],
'1000 items' => [1000],
'10000 items' => [10000],
'100000 items' => [100000],
];
}
}
......@@ -12,18 +12,18 @@ class CompositeExpressionTest extends DbalTestCase
{
public function testCount() : void
{
$expr = new CompositeExpression(CompositeExpression::TYPE_OR, ['u.group_id = 1']);
$expr = CompositeExpression::or('u.group_id = 1');
self::assertCount(1, $expr);
$expr->add('u.group_id = 2');
$expr = $expr->with('u.group_id = 2');
self::assertCount(2, $expr);
}
public function testAdd() : void
{
$expr = new CompositeExpression(CompositeExpression::TYPE_OR, ['u.group_id = 1']);
$expr = CompositeExpression::or('u.group_id = 1');
self::assertCount(1, $expr);
......@@ -31,7 +31,7 @@ class CompositeExpressionTest extends DbalTestCase
self::assertCount(1, $expr);
$expr->add(new CompositeExpression(CompositeExpression::TYPE_OR, ['u.user_id = 1']));
$expr->add(CompositeExpression::or('u.user_id = 1'));
self::assertCount(2, $expr);
......@@ -44,6 +44,26 @@ class CompositeExpressionTest extends DbalTestCase
self::assertCount(3, $expr);
}
public function testWith() : void
{
$expr = CompositeExpression::or('u.group_id = 1');
self::assertCount(1, $expr);
// test immutability
$expr->with(CompositeExpression::or('u.user_id = 1'));
self::assertCount(1, $expr);
$expr = $expr->with(CompositeExpression::or('u.user_id = 1'));
self::assertCount(2, $expr);
$expr = $expr->with('u.user_id = 1');
self::assertCount(3, $expr);
}
/**
* @param string[]|CompositeExpression[] $parts
*
......@@ -86,9 +106,9 @@ class CompositeExpressionTest extends DbalTestCase
CompositeExpression::TYPE_AND,
[
'u.user = 1',
new CompositeExpression(
CompositeExpression::TYPE_OR,
['u.group_id = 1', 'u.group_id = 2']
CompositeExpression::or(
'u.group_id = 1',
'u.group_id = 2'
),
],
'(u.user = 1) AND ((u.group_id = 1) OR (u.group_id = 2))',
......@@ -97,9 +117,9 @@ class CompositeExpressionTest extends DbalTestCase
CompositeExpression::TYPE_OR,
[
'u.group_id = 1',
new CompositeExpression(
CompositeExpression::TYPE_AND,
['u.user = 1', 'u.group_id = 2']
CompositeExpression::and(
'u.user = 1',
'u.group_id = 2'
),
],
'(u.group_id = 1) OR ((u.user = 1) AND (u.group_id = 2))',
......
......@@ -29,7 +29,19 @@ class ExpressionBuilderTest extends DbalTestCase
/**
* @param string[]|CompositeExpression[] $parts
*
* @dataProvider provideDataForAndX
* @dataProvider provideDataForAnd
*/
public function testAnd(array $parts, string $expected) : void
{
$composite = $this->expr->and(...$parts);
self::assertEquals($expected, (string) $composite);
}
/**
* @param string[]|CompositeExpression[] $parts
*
* @dataProvider provideDataForAnd
*/
public function testAndX(array $parts, string $expected) : void
{
......@@ -45,7 +57,7 @@ class ExpressionBuilderTest extends DbalTestCase
/**
* @return mixed[][]
*/
public static function provideDataForAndX() : iterable
public static function provideDataForAnd() : iterable
{
return [
[
......@@ -67,9 +79,9 @@ class ExpressionBuilderTest extends DbalTestCase
[
[
'u.user = 1',
new CompositeExpression(
CompositeExpression::TYPE_OR,
['u.group_id = 1', 'u.group_id = 2']
CompositeExpression::or(
'u.group_id = 1',
'u.group_id = 2'
),
],
'(u.user = 1) AND ((u.group_id = 1) OR (u.group_id = 2))',
......@@ -77,9 +89,9 @@ class ExpressionBuilderTest extends DbalTestCase
[
[
'u.group_id = 1',
new CompositeExpression(
CompositeExpression::TYPE_AND,
['u.user = 1', 'u.group_id = 2']
CompositeExpression::and(
'u.user = 1',
'u.group_id = 2'
),
],
'(u.group_id = 1) AND ((u.user = 1) AND (u.group_id = 2))',
......@@ -90,7 +102,19 @@ class ExpressionBuilderTest extends DbalTestCase
/**
* @param string[]|CompositeExpression[] $parts
*
* @dataProvider provideDataForOrX
* @dataProvider provideDataForOr
*/
public function testOr(array $parts, string $expected) : void
{
$composite = $this->expr->or(...$parts);
self::assertEquals($expected, (string) $composite);
}
/**
* @param string[]|CompositeExpression[] $parts
*
* @dataProvider provideDataForOr
*/
public function testOrX(array $parts, string $expected) : void
{
......@@ -106,7 +130,7 @@ class ExpressionBuilderTest extends DbalTestCase
/**
* @return mixed[][]
*/
public static function provideDataForOrX() : iterable
public static function provideDataForOr() : iterable
{
return [
[
......@@ -128,9 +152,9 @@ class ExpressionBuilderTest extends DbalTestCase
[
[
'u.user = 1',
new CompositeExpression(
CompositeExpression::TYPE_OR,
['u.group_id = 1', 'u.group_id = 2']
CompositeExpression::or(
'u.group_id = 1',
'u.group_id = 2'
),
],
'(u.user = 1) OR ((u.group_id = 1) OR (u.group_id = 2))',
......@@ -138,9 +162,9 @@ class ExpressionBuilderTest extends DbalTestCase
[
[
'u.group_id = 1',
new CompositeExpression(
CompositeExpression::TYPE_AND,
['u.user = 1', 'u.group_id = 2']
CompositeExpression::and(
'u.user = 1',
'u.group_id = 2'
),
],
'(u.group_id = 1) OR ((u.user = 1) AND (u.group_id = 2))',
......
......@@ -68,7 +68,7 @@ class QueryBuilderTest extends DbalTestCase
$qb->select('u.id')
->from('users', 'u')
->where($expr->andX($expr->eq('u.nickname', '?')));
->where($expr->and($expr->eq('u.nickname', '?')));
self::assertEquals('SELECT u.id FROM users u WHERE u.nickname = ?', (string) $qb);
}
......
<?php
namespace Doctrine\Tests;
use function microtime;
/**
* Base class for all DBAL performance tests.
*
* Tests implemented in this class must call startTiming at the beginning
* and stopTiming at the end of all tests. Tests that do not start or stop
* timing will fail.
*/
abstract class DbalPerformanceTestCase extends DbalFunctionalTestCase
{
/**
* time the test started
*
* @var float
*/
private $startTime;
/**
* elapsed run time of the last test
*
* @var float
*/
private $runTime;
/**
* {@inheritdoc}
*/
protected function assertPostConditions() : void
{
// If a perf test doesn't start or stop, it fails.
self::assertNotNull($this->startTime, 'Test timing was started');
self::assertNotNull($this->runTime, 'Test timing was stopped');
}
/**
* begin timing
*/
protected function startTiming() : void
{
$this->startTime = microtime(true);
}
/**
* end timing
*/
protected function stopTiming() : void
{
$this->runTime = microtime(true) - $this->startTime;
}
/**
* @return float elapsed test execution time
*/
public function getTime() : float
{
return $this->runTime;
}
}
<?php
namespace Doctrine\Tests;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestListener;
use PHPUnit\Framework\TestListenerDefaultImplementation;
use function get_class;
use function printf;
use function str_replace;
/**
* Listener for collecting and reporting results of performance tests
*/
class DbalPerformanceTestListener implements TestListener
{
use TestListenerDefaultImplementation;
/** @var string[][] */
private $timings = [];
/**
* {@inheritdoc}
*/
public function endTest(Test $test, float $time) : void
{
// This listener only applies to performance tests.
if (! ($test instanceof DbalPerformanceTestCase)) {
return;
}
// we identify perf tests by class, method, and dataset
$class = str_replace('\\Doctrine\\Tests\\DBAL\\Performance\\', '', get_class($test));
if (! isset($this->timings[$class])) {
$this->timings[$class] = [];
}
// Store timing data for each test in the order they were run.
$this->timings[$class][$test->getName(true)] = $test->getTime();
}
/**
* Report performance test timings.
*
* Note: __destruct is used here because PHPUnit doesn't have a
* 'All tests over' hook.
*/
public function __destruct()
{
if (empty($this->timings)) {
return;
}
// Report timings.
print "\nPerformance test results:\n\n";
foreach ($this->timings as $class => $tests) {
printf("%s:\n", $class);
foreach ($tests as $test => $time) {
printf("\t%s: %.3f seconds\n", $test, $time);
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment