From f8a123fdb67c1417b3a883aebf28836d4a912ef9 Mon Sep 17 00:00:00 2001
From: Morton Jonuschat <m.jonuschat@mojocode.de>
Date: Mon, 18 Apr 2016 20:24:30 +0200
Subject: [PATCH] [TASK] Doctrine: Extend ExpressionBuilder with bitwise and
 support

Extend the ExpressionBuilder with support for creating bitwise and
operations. Oracle needs a special SQL function to perform an &
operation and the core requires bitwise operations.

Releases: master
Resolves: #75563
Change-Id: I2ae7e20a9a4ced5b16330c94a3e9a6f156ba5f61
Reviewed-on: https://review.typo3.org/47760
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
---
 .../Query/Expression/ExpressionBuilder.php    | 26 +++++++++++++++
 .../Expression/ExpressionBuilderTest.php      | 33 +++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php b/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
index a4337c35184d..3246950503d7 100644
--- a/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
+++ b/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
@@ -326,6 +326,32 @@ class ExpressionBuilder
         }
     }
 
+    /**
+     * Creates a bitwise AND expression with the given arguments.
+     *
+     * @param string $fieldName The fieldname. Will be quoted according to database platform automatically.
+     * @param int $value Argument to be used in the bitwise AND operation
+     * @return string
+     */
+    public function bitAnd(string $fieldName, int $value): string
+    {
+        switch ($this->connection->getDatabasePlatform()->getName()) {
+            case 'oci8':
+            case 'pdo_oracle':
+                return sprintf(
+                    'BITAND(%s, %s)',
+                    $this->connection->quoteIdentifier($fieldName),
+                    $value
+                );
+            default:
+                return $this->comparison(
+                    $this->connection->quoteIdentifier($fieldName),
+                    '&',
+                    $value
+                );
+        }
+    }
+
     /**
      * Quotes a given input parameter.
      *
diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
index c484fd003023..1224f98f3887 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
@@ -271,6 +271,39 @@ class ExpressionBuilderTest extends UnitTestCase
         $this->assertSame('any(string_to_array("aField", \',\')) = \'1\'', $result);
     }
 
+    /**
+     * @test
+     */
+    public function defaultBitwiseAnd()
+    {
+        $databasePlatform = $this->prophesize(MockPlatform::class);
+
+        $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
+            return '"' . $args[0] . '"';
+        });
+
+        $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
+
+        $this->assertSame('"aField" & 1', $this->subject->bitAnd('aField', 1));
+    }
+
+    /**
+     * @test
+     */
+    public function bitwiseAndForOracle()
+    {
+        $databasePlatform = $this->prophesize(MockPlatform::class);
+        $databasePlatform->getName()->willReturn('pdo_oracle');
+
+        $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
+            return '"' . $args[0] . '"';
+        });
+
+        $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
+
+        $this->assertSame('BITAND("aField", 1)', $this->subject->bitAnd('aField', 1));
+    }
+
     /**
      * @test
      */
-- 
GitLab