diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index a3709ed..1007ef6 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -1,14 +1,17 @@
-
-
- src
- tests
-
-
-
-
-
-
-
- tests/*
-
-
+
+
+ src
+ tests
+
+
+
+
+
+
+
+ tests/*
+
+
+ src/Doctrine/DBAL/Platforms/MicrosoftAccessPlatform.php
+
+
diff --git a/src/Doctrine/DBAL/Platforms/MicrosoftAccessPlatform.php b/src/Doctrine/DBAL/Platforms/MicrosoftAccessPlatform.php
index 055f2dd..7ac8756 100644
--- a/src/Doctrine/DBAL/Platforms/MicrosoftAccessPlatform.php
+++ b/src/Doctrine/DBAL/Platforms/MicrosoftAccessPlatform.php
@@ -8,9 +8,6 @@
final class MicrosoftAccessPlatform extends SQLServer2012Platform
{
- /**
- * {@inheritDoc}
- */
public function getName(): string
{
return 'msaccess';
@@ -77,9 +74,6 @@ protected function initializeDoctrineTypeMappings()
];
}
- /**
- * {@inheritDoc}
- */
protected function getReservedKeywordsClass(): string
{
return MicrosoftAccessKeywords::class;
@@ -88,40 +82,34 @@ protected function getReservedKeywordsClass(): string
/**
* {@inheritDoc}
*
- * @see https://github.com/doctrine/dbal/blob/2.12.x/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php#L1285
+ * @see \Doctrine\DBAL\Platforms\SQLServerPlatform::doModifyLimitQuery
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
{
$where = [];
if ($offset > 0) {
- $where[] = sprintf('doctrine_rownum >= %d', $offset + 1);
+ $where[] = \sprintf('doctrine_rownum >= %d', $offset + 1);
}
- if ($limit !== null) {
- $where[] = sprintf('doctrine_rownum <= %d', $offset + $limit);
- $top = sprintf('TOP %d', $offset + $limit);
+ if (null !== $limit) {
+ $where[] = \sprintf('doctrine_rownum <= %d', $offset + $limit);
+ $top = \sprintf('TOP %d', $offset + $limit);
} else {
$top = 'TOP 9223372036854775807';
}
- if (empty($where)) {
+ if (0 === \count($where)) {
return $query;
}
- // We'll find a SELECT or SELECT distinct and prepend TOP n to it
- // Even if the TOP n is very large, the use of a CTE will
- // allow the SQL Server query planner to optimize it so it doesn't
- // actually scan the entire range covered by the TOP clause.
- if (!preg_match('/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/is', $query, $matches)) {
+ if (!\preg_match('/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/is', $query, $matches)) {
return $query;
}
$query = $matches[1] . $top . ' ' . $matches[2];
- if (stristr($query, 'ORDER BY')) {
- // Inner order by is not valid in SQL Server for our purposes
- // unless it's in a TOP N subquery.
+ if (\stristr($query, 'ORDER BY')) {
$query = $this->scrubInnerOrderBy($query);
}
@@ -129,32 +117,31 @@ protected function doModifyLimitQuery($query, $limit, $offset = null)
}
/**
- * Remove ORDER BY clauses in sub queries - they're not supported by MS Access.
- * Caveat: will leave ORDER BY in TOP N sub queries.
- *
- * @param string $query
+ * {@inheritDoc}
*
- * @return string
+ * @see \Doctrine\DBAL\Platforms\SQLServerPlatform::scrubInnerOrderBy
*/
- private function scrubInnerOrderBy(string $query)
+ private function scrubInnerOrderBy(string $query): string
{
- $count = substr_count(strtoupper($query), 'ORDER BY');
+ $count = \substr_count(\strtoupper($query), 'ORDER BY');
$offset = 0;
while ($count-- > 0) {
- $orderByPos = stripos($query, ' ORDER BY', $offset);
- if ($orderByPos === false) {
+ $orderByPos = \stripos($query, ' ORDER BY', $offset);
+ if (false === $orderByPos) {
break;
}
- $qLen = strlen($query);
+ $qLen = \strlen($query);
$parenCount = 0;
$currentPosition = $orderByPos;
while ($parenCount >= 0 && $currentPosition < $qLen) {
- if ($query[$currentPosition] === '(') {
+ if ('(' === $query[$currentPosition]) {
$parenCount++;
- } elseif ($query[$currentPosition] === ')') {
+ }
+
+ if (')' === $query[$currentPosition]) {
$parenCount--;
}
@@ -165,6 +152,7 @@ private function scrubInnerOrderBy(string $query)
// If the order by clause is in a TOP N subquery, do not remove
// it and continue iteration from the current position.
$offset = $currentPosition;
+
continue;
}
@@ -172,7 +160,7 @@ private function scrubInnerOrderBy(string $query)
continue;
}
- $query = substr($query, 0, $orderByPos) . substr($query, $currentPosition - 1);
+ $query = \substr($query, 0, $orderByPos) . \substr($query, $currentPosition - 1);
$offset = $orderByPos;
}
@@ -180,34 +168,29 @@ private function scrubInnerOrderBy(string $query)
}
/**
- * Check an ORDER BY clause to see if it is in a TOP N query or sub query.
- *
- * @param string $query The query
- * @param int $currentPosition Start position of ORDER BY clause
+ * {@inheritDoc}
*
- * @return bool true if ORDER BY is in a TOP N query, false otherwise
+ * @see \Doctrine\DBAL\Platforms\SQLServerPlatform::isOrderByInTopNSubquery
*/
- private function isOrderByInTopNSubquery(string $query, int $currentPosition)
+ private function isOrderByInTopNSubquery(string $query, int $currentPosition): bool
{
- // Grab query text on the same nesting level as the ORDER BY clause we're examining.
$subQueryBuffer = '';
$parenCount = 0;
- // If $parenCount goes negative, we've exited the subquery we're examining.
- // If $currentPosition goes negative, we've reached the beginning of the query.
while ($parenCount >= 0 && $currentPosition >= 0) {
- if ($query[$currentPosition] === '(') {
+ if ('(' === $query[$currentPosition]) {
$parenCount--;
- } elseif ($query[$currentPosition] === ')') {
+ }
+
+ if (')' === $query[$currentPosition]) {
$parenCount++;
}
- // Only yank query text on the same nesting level as the ORDER BY clause.
- $subQueryBuffer = ($parenCount === 0 ? $query[$currentPosition] : ' ') . $subQueryBuffer;
+ $subQueryBuffer = (0 === $parenCount ? $query[$currentPosition] : ' ') . $subQueryBuffer;
$currentPosition--;
}
- return (bool)preg_match('/SELECT\s+(DISTINCT\s+)?TOP\s/i', $subQueryBuffer);
+ return (bool)\preg_match('/SELECT\s+(DISTINCT\s+)?TOP\s/i', $subQueryBuffer);
}
}
diff --git a/tests/Doctrine/DBAL/Platforms/MicrosoftAccessPlatformTest.php b/tests/Doctrine/DBAL/Platforms/MicrosoftAccessPlatformTest.php
new file mode 100644
index 0000000..5c0e60f
--- /dev/null
+++ b/tests/Doctrine/DBAL/Platforms/MicrosoftAccessPlatformTest.php
@@ -0,0 +1,30 @@
+createQueryBuilder()
+ ->select('*')
+ ->from(self::TABLE_NAME)
+ ->setMaxResults(2)
+ ->execute();
+
+ $rows = $result->fetchAllAssociative();
+
+ $this->assertIsArray($rows);
+ $this->assertCount(2, $rows);
+ }
+}