Browse Source

Remove deprecated CaseExpression

Corey Taylor 4 years ago
parent
commit
00f0481fb7

+ 0 - 5
psalm-baseline.xml

@@ -42,11 +42,6 @@
       <code>$request</code>
     </ArgumentTypeCoercion>
   </file>
-  <file src="src/Database/Expression/QueryExpression.php">
-    <DeprecatedClass occurrences="1">
-      <code>new CaseExpression($conditions, $values, $types)</code>
-    </DeprecatedClass>
-  </file>
   <file src="src/Database/Statement/PDOStatement.php">
     <NonInvariantDocblockPropertyType occurrences="1">
       <code>$_statement</code>

+ 0 - 262
src/Database/Expression/CaseExpression.php

@@ -1,262 +0,0 @@
-<?php
-declare(strict_types=1);
-
-/**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link          https://cakephp.org CakePHP(tm) Project
- * @since         3.0.0
- * @license       https://opensource.org/licenses/mit-license.php MIT License
- */
-namespace Cake\Database\Expression;
-
-use Cake\Database\ExpressionInterface;
-use Cake\Database\Type\ExpressionTypeCasterTrait;
-use Cake\Database\ValueBinder;
-use Closure;
-
-/**
- * This class represents a SQL Case statement
- *
- * @deprecated 4.3.0 Use QueryExpression::case() or CaseStatementExpression instead
- */
-class CaseExpression implements ExpressionInterface
-{
-    use ExpressionTypeCasterTrait;
-
-    /**
-     * A list of strings or other expression objects that represent the conditions of
-     * the case statement. For example one key of the array might look like "sum > :value"
-     *
-     * @var array
-     */
-    protected array $_conditions = [];
-
-    /**
-     * Values that are associated with the conditions in the $_conditions array.
-     * Each value represents the 'true' value for the condition with the corresponding key.
-     *
-     * @var array
-     */
-    protected array $_values = [];
-
-    /**
-     * The `ELSE` value for the case statement. If null then no `ELSE` will be included.
-     *
-     * @var \Cake\Database\ExpressionInterface|array|string|null
-     */
-    protected ExpressionInterface|array|string|null $_elseValue = null;
-
-    /**
-     * Constructs the case expression
-     *
-     * @param \Cake\Database\ExpressionInterface|array $conditions The conditions to test. Must be a ExpressionInterface
-     * instance, or an array of ExpressionInterface instances.
-     * @param \Cake\Database\ExpressionInterface|array|string|float|int|bool|null $values Associative array of values to be associated with the.
-     * conditions passed in $conditions. If there are more $values than $conditions,
-     * the last $value is used as the `ELSE` value.
-     * @param array<string> $types Associative array of types to be associated with the values
-     * passed in $values
-     */
-    public function __construct(
-        ExpressionInterface|array $conditions = [],
-        ExpressionInterface|array|string|float|int|bool|null $values = [],
-        array|string $types = []
-    ) {
-        $conditions = is_array($conditions) ? $conditions : [$conditions];
-        $values = is_array($values) ? $values : [$values];
-        /**
-         * @psalm-suppress TypeDoesNotContainType,RedundantCondition
-         */
-        $types = is_array($types) ? $types : [$types];
-
-        if (!empty($conditions)) {
-            $this->add($conditions, $values, $types);
-        }
-
-        if (count($values) > count($conditions)) {
-            end($values);
-            $key = key($values);
-            $this->elseValue($values[$key], $types[$key] ?? null);
-        }
-    }
-
-    /**
-     * Adds one or more conditions and their respective true values to the case object.
-     * Conditions must be a one dimensional array or a QueryExpression.
-     * The trueValues must be a similar structure, but may contain a string value.
-     *
-     * @param \Cake\Database\ExpressionInterface|array $conditions Must be a ExpressionInterface instance,
-     *   or an array of ExpressionInterface instances.
-     * @param \Cake\Database\ExpressionInterface|array|string|float|int|bool|null $values Associative array of values of each condition.
-     * @param array<string>|string $types Associative array of types to be associated with the values.
-     * @return $this
-     */
-    public function add(
-        ExpressionInterface|array $conditions = [],
-        ExpressionInterface|array|string|float|int|bool|null $values = [],
-        array|string $types = []
-    ) {
-        $conditions = is_array($conditions) ? $conditions : [$conditions];
-        $values = is_array($values) ? $values : [$values];
-        $types = is_array($types) ? $types : [$types];
-
-        $this->_addExpressions($conditions, $values, $types);
-
-        return $this;
-    }
-
-    /**
-     * Iterates over the passed in conditions and ensures that there is a matching true value for each.
-     * If no matching true value, then it is defaulted to '1'.
-     *
-     * @param array $conditions Array of ExpressionInterface instances.
-     * @param array<mixed> $values Associative array of values of each condition
-     * @param array<string> $types Associative array of types to be associated with the values
-     * @return void
-     */
-    protected function _addExpressions(array $conditions, array $values, array $types): void
-    {
-        $rawValues = array_values($values);
-        $keyValues = array_keys($values);
-
-        foreach ($conditions as $k => $c) {
-            $numericKey = is_numeric($k);
-
-            if ($numericKey && empty($c)) {
-                continue;
-            }
-
-            if (!$c instanceof ExpressionInterface) {
-                continue;
-            }
-
-            $this->_conditions[] = $c;
-            $value = $rawValues[$k] ?? 1;
-
-            if ($value === 'literal') {
-                $value = $keyValues[$k];
-                $this->_values[] = $value;
-                continue;
-            }
-
-            if ($value === 'identifier') {
-                /** @var string $identifier */
-                $identifier = $keyValues[$k];
-                $value = new IdentifierExpression($identifier);
-                $this->_values[] = $value;
-                continue;
-            }
-
-            $type = $types[$k] ?? null;
-
-            if ($type !== null && !$value instanceof ExpressionInterface) {
-                $value = $this->_castToExpression($value, $type);
-            }
-
-            if ($value instanceof ExpressionInterface) {
-                $this->_values[] = $value;
-                continue;
-            }
-
-            $this->_values[] = ['value' => $value, 'type' => $type];
-        }
-    }
-
-    /**
-     * Sets the default value
-     *
-     * @param \Cake\Database\ExpressionInterface|array|string|float|int|bool|null $value Value to set
-     * @param string|null $type Type of value
-     * @return void
-     */
-    public function elseValue(
-        ExpressionInterface|array|string|float|int|bool|null $value = null,
-        ?string $type = null
-    ): void {
-        if (is_array($value)) {
-            end($value);
-            $value = key($value);
-        }
-
-        if ($value !== null && !$value instanceof ExpressionInterface) {
-            $value = $this->_castToExpression($value, $type);
-        }
-
-        if (!$value instanceof ExpressionInterface) {
-            $value = ['value' => $value, 'type' => $type];
-        }
-
-        $this->_elseValue = $value;
-    }
-
-    /**
-     * Compiles the relevant parts into sql
-     *
-     * @param \Cake\Database\ExpressionInterface|array|string $part The part to compile
-     * @param \Cake\Database\ValueBinder $binder Sql generator
-     * @return string
-     */
-    protected function _compile(ExpressionInterface|array|string $part, ValueBinder $binder): string
-    {
-        if ($part instanceof ExpressionInterface) {
-            $part = $part->sql($binder);
-        } elseif (is_array($part)) {
-            $placeholder = $binder->placeholder('param');
-            $binder->bind($placeholder, $part['value'], $part['type']);
-            $part = $placeholder;
-        }
-
-        return $part;
-    }
-
-    /**
-     * Converts the Node into a SQL string fragment.
-     *
-     * @param \Cake\Database\ValueBinder $binder Placeholder generator object
-     * @return string
-     */
-    public function sql(ValueBinder $binder): string
-    {
-        $parts = [];
-        $parts[] = 'CASE';
-        foreach ($this->_conditions as $k => $part) {
-            $value = $this->_values[$k];
-            $parts[] = 'WHEN ' . $this->_compile($part, $binder) . ' THEN ' . $this->_compile($value, $binder);
-        }
-        if ($this->_elseValue !== null) {
-            $parts[] = 'ELSE';
-            $parts[] = $this->_compile($this->_elseValue, $binder);
-        }
-        $parts[] = 'END';
-
-        return implode(' ', $parts);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public function traverse(Closure $callback)
-    {
-        foreach (['_conditions', '_values'] as $part) {
-            foreach ($this->{$part} as $c) {
-                if ($c instanceof ExpressionInterface) {
-                    $callback($c);
-                    $c->traverse($callback);
-                }
-            }
-        }
-        if ($this->_elseValue instanceof ExpressionInterface) {
-            $callback($this->_elseValue);
-            $this->_elseValue->traverse($callback);
-        }
-
-        return $this;
-    }
-}

+ 0 - 23
src/Database/Expression/QueryExpression.php

@@ -336,29 +336,6 @@ class QueryExpression implements ExpressionInterface, Countable
     }
 
     /**
-     * Adds a new case expression to the expression object
-     *
-     * @param \Cake\Database\ExpressionInterface|array $conditions The conditions to test. Must be a ExpressionInterface
-     * instance, or an array of ExpressionInterface instances.
-     * @param \Cake\Database\ExpressionInterface|array|string|float|int|bool|null $values Associative array of values to be associated with the.
-     * conditions passed in $conditions. If there are more $values than $conditions,
-     * the last $value is used as the `ELSE` value.
-     * @param array<string> $types Associative array of types to be associated with the values
-     * passed in $values
-     * @return $this
-     * @deprecated 4.3.0 Use QueryExpression::case() or CaseStatementExpression instead
-     */
-    public function addCase(
-        ExpressionInterface|array $conditions,
-        ExpressionInterface|array|string|float|int|bool|null $values = [],
-        array|string $types = []
-    ) {
-        deprecationWarning('4.3.0', 'QueryExpression::addCase() is deprecated, use case() instead.');
-
-        return $this->add(new CaseExpression($conditions, $values, $types));
-    }
-
-    /**
      * Returns a new case expression object.
      *
      * When a value is set, the syntax generated is

+ 0 - 113
tests/TestCase/Database/Expression/CaseExpressionTest.php

@@ -1,113 +0,0 @@
-<?php
-declare(strict_types=1);
-
-/**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The Open Group Test Suite License
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link          https://cakephp.org CakePHP(tm) Project
- * @since         3.0.0
- * @license       https://opensource.org/licenses/mit-license.php MIT License
- */
-namespace Cake\Test\TestCase\Database\Expression;
-
-use Cake\Database\Expression\CaseExpression;
-use Cake\Database\Expression\QueryExpression;
-use Cake\Database\ValueBinder;
-use Cake\TestSuite\TestCase;
-
-/**
- * Tests CaseExpression class
- */
-class CaseExpressionTest extends TestCase
-{
-    /**
-     * Test that the sql output works correctly
-     */
-    public function testSqlOutput(): void
-    {
-        $expr = new QueryExpression();
-        $expr->eq('test', 'true');
-        $expr2 = new QueryExpression();
-        $expr2->eq('test2', 'false');
-
-        $caseExpression = new CaseExpression($expr, 'foobar');
-        $expected = 'CASE WHEN test = :c0 THEN :param1 END';
-        $this->assertSame($expected, $caseExpression->sql(new ValueBinder()));
-
-        $caseExpression->add($expr2);
-        $expected = 'CASE WHEN test = :c0 THEN :param1 WHEN test2 = :c2 THEN :param3 END';
-        $this->assertSame($expected, $caseExpression->sql(new ValueBinder()));
-
-        $caseExpression = new CaseExpression($expr, ['foobar', 'else']);
-        $expected = 'CASE WHEN test = :c0 THEN :param1 ELSE :param2 END';
-        $this->assertSame($expected, $caseExpression->sql(new ValueBinder()));
-
-        $caseExpression = new CaseExpression([$expr], ['foobar', 'else']);
-        $expected = 'CASE WHEN test = :c0 THEN :param1 ELSE :param2 END';
-        $this->assertSame($expected, $caseExpression->sql(new ValueBinder()));
-
-        $caseExpression = new CaseExpression([$expr], ['foobar' => 'literal', 'else']);
-        $expected = 'CASE WHEN test = :c0 THEN foobar ELSE :param1 END';
-        $this->assertSame($expected, $caseExpression->sql(new ValueBinder()));
-    }
-
-    /**
-     * Test sql generation with 0 case.
-     */
-    public function testSqlOutputZero(): void
-    {
-        $expression = new QueryExpression();
-        $expression->add(['id' => 'test']);
-        $caseExpression = new CaseExpression([$expression], [0], ['integer']);
-        $expected = 'CASE WHEN id = :c0 THEN :param1 END';
-        $binder = new ValueBinder();
-        $this->assertSame($expected, $caseExpression->sql($binder));
-        $expected = [
-            ':c0' => ['value' => 'test', 'type' => null, 'placeholder' => 'c0'],
-            ':param1' => ['value' => 0, 'type' => 'integer', 'placeholder' => 'param1'],
-        ];
-        $this->assertEquals($expected, $binder->bindings());
-    }
-
-    /**
-     * Tests that the expression is correctly traversed
-     */
-    public function testTraverse(): void
-    {
-        $count = 0;
-        $visitor = function () use (&$count): void {
-            $count++;
-        };
-
-        $expr = new QueryExpression();
-        $expr->eq('test', 'true');
-        $expr2 = new QueryExpression();
-        $expr2->eq('test', 'false');
-        $caseExpression = new CaseExpression([$expr, $expr2]);
-        $caseExpression->traverse($visitor);
-        $this->assertSame(4, $count);
-    }
-
-    /**
-     * Test cloning
-     */
-    public function testClone(): void
-    {
-        $expr = new QueryExpression();
-        $expr->eq('test', 'true');
-        $expr2 = new QueryExpression();
-        $expr2->eq('test2', 'false');
-
-        $caseExpression = new CaseExpression([$expr, $expr2], 'foobar');
-        $dupe = clone $caseExpression;
-        $dupe->elseValue('nope');
-
-        $this->assertNotEquals($caseExpression, $dupe);
-        $this->assertNotSame($caseExpression, $dupe);
-    }
-}

+ 0 - 11
tests/TestCase/Database/Expression/QueryExpressionTest.php

@@ -201,17 +201,6 @@ class QueryExpressionTest extends TestCase
         );
     }
 
-    /**
-     * Test deprecated adding of case statement.
-     */
-    public function testDeprecatedAddCaseStatement(): void
-    {
-        $this->expectDeprecation();
-        $this->expectDeprecationMessage('QueryExpression::addCase() is deprecated, use case() instead.');
-
-        (new QueryExpression())->addCase([]);
-    }
-
     public function testCaseWithoutValue(): void
     {
         $expression = (new QueryExpression())

+ 0 - 29
tests/TestCase/Database/ExpressionTypeCastingTest.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
 namespace Cake\Test\TestCase\Database;
 
 use Cake\Database\Expression\BetweenExpression;
-use Cake\Database\Expression\CaseExpression;
 use Cake\Database\Expression\ComparisonExpression;
 use Cake\Database\Expression\FunctionExpression;
 use Cake\Database\Expression\ValuesExpression;
@@ -102,34 +101,6 @@ class ExpressionTypeCastingTest extends TestCase
     }
 
     /**
-     * Tests that the Case expressions converts values to expressions correctly
-     */
-    public function testCaseExpression(): void
-    {
-        $case = new CaseExpression(
-            [new ComparisonExpression('foo', '1', 'string', '=')],
-            ['value1', 'value2'],
-            ['test', 'test']
-        );
-
-        $binder = new ValueBinder();
-        $sql = $case->sql($binder);
-        $this->assertSame('CASE WHEN foo = :c0 THEN CONCAT(:param1, :param2) ELSE CONCAT(:param3, :param4) END', $sql);
-
-        $this->assertSame('1', $binder->bindings()[':c0']['value']);
-        $this->assertSame('value1', $binder->bindings()[':param1']['value']);
-        $this->assertSame('value2', $binder->bindings()[':param3']['value']);
-
-        $expressions = [];
-        $case->traverse(function ($exp) use (&$expressions): void {
-            $expressions[] = $exp instanceof FunctionExpression ? 1 : 0;
-        });
-
-        $result = array_sum($expressions);
-        $this->assertSame(2, $result, 'Missing expressions in the tree');
-    }
-
-    /**
      * Tests that values in FunctionExpressions are converted to expressions correctly
      */
     public function testFunctionExpression(): void

+ 0 - 115
tests/TestCase/Database/QueryTest.php

@@ -4104,121 +4104,6 @@ class QueryTest extends TestCase
     }
 
     /**
-     * Tests that case statements work correctly for various use-cases.
-     *
-     * @deprecated
-     */
-    public function testSqlCaseStatement(): void
-    {
-        $query = new Query($this->connection);
-        $publishedCase = null;
-        $notPublishedCase = null;
-        $this->deprecated(function () use ($query, &$publishedCase, &$notPublishedCase) {
-            $publishedCase = $query
-                ->newExpr()
-                ->addCase(
-                    $query
-                        ->newExpr()
-                        ->add(['published' => 'Y']),
-                    1,
-                    'integer'
-                );
-            $notPublishedCase = $query
-                ->newExpr()
-                ->addCase(
-                    $query
-                        ->newExpr()
-                        ->add(['published' => 'N']),
-                    1,
-                    'integer'
-                );
-        });
-
-        // Postgres requires the case statement to be cast to a integer
-        if ($this->connection->getDriver() instanceof Postgres) {
-            $publishedCase = $query->func()->cast($publishedCase, 'integer');
-            $notPublishedCase = $query->func()->cast($notPublishedCase, 'integer');
-        }
-
-        $results = $query
-            ->select([
-                'published' => $query->func()->sum($publishedCase),
-                'not_published' => $query->func()->sum($notPublishedCase),
-            ])
-            ->from(['comments'])
-            ->execute()
-            ->fetchAll('assoc');
-
-        $this->assertEquals(5, $results[0]['published']);
-        $this->assertEquals(1, $results[0]['not_published']);
-
-        $query = new Query($this->connection);
-        $query
-            ->insert(['article_id', 'user_id', 'comment', 'published'])
-            ->into('comments')
-            ->values([
-                'article_id' => 2,
-                'user_id' => 1,
-                'comment' => 'In limbo',
-                'published' => 'L',
-            ])
-            ->execute()
-            ->closeCursor();
-
-        $query = new Query($this->connection);
-        $conditions = [
-            $query
-                ->newExpr()
-                ->add(['published' => 'Y']),
-            $query
-                ->newExpr()
-                ->add(['published' => 'N']),
-        ];
-        $values = [
-            'Published',
-            'Not published',
-            'None',
-        ];
-        $this->deprecated(function () use ($query, $conditions, $values) {
-            $query
-                ->select([
-                    'id',
-                    'comment',
-                    'status' => $query->newExpr()->addCase($conditions, $values),
-                ])
-                ->from(['comments']);
-        });
-        $results = $query
-            ->execute()
-            ->fetchAll('assoc');
-
-        $this->assertSame('Published', $results[2]['status']);
-        $this->assertSame('Not published', $results[3]['status']);
-        $this->assertSame('None', $results[6]['status']);
-
-        $query = new Query($this->connection);
-        $this->deprecated(function () use ($query) {
-            $query->select(['id'])
-                ->from('articles')
-                ->orderAsc(function (QueryExpression $exp, Query $query) {
-                    return $exp->addCase(
-                        [$query->newExpr()->add(['author_id' => 1])],
-                        [1, $query->identifier('id')],
-                        ['integer', null]
-                    );
-                })
-                ->orderAsc('id');
-        });
-        $result = $query->execute()->fetchAll('assoc');
-        $expected = [
-            ['id' => 1],
-            ['id' => 3],
-            ['id' => 2],
-        ];
-        $this->assertEquals($expected, $result);
-    }
-
-    /**
      * Shows that bufferResults(false) will prevent client-side results buffering
      */
     public function testUnbufferedQuery(): void