diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 5adb0922..c8c39632 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -38,6 +38,7 @@ doctrine: string_functions: regexp: DoctrineExtensions\Query\Mysql\Regexp ifnull: DoctrineExtensions\Query\Mysql\IfNull + field: DoctrineExtensions\Query\Mysql\Field when@test: doctrine: diff --git a/src/Doctrine/SQLiteRegexExtension.php b/src/Doctrine/SQLiteRegexExtension.php index b5839c63..045d050c 100644 --- a/src/Doctrine/SQLiteRegexExtension.php +++ b/src/Doctrine/SQLiteRegexExtension.php @@ -47,14 +47,48 @@ class SQLiteRegexExtension //Ensure that the function really exists on the connection, as it is marked as experimental according to PHP documentation if($native_connection instanceof \PDO && method_exists($native_connection, 'sqliteCreateFunction' )) { - $native_connection->sqliteCreateFunction('REGEXP', function ($pattern, $value) { - try { - return (mb_ereg($pattern, $value)) ? 1 : 0; - } catch (\ErrorException $e) { - throw InvalidRegexException::fromMBRegexError($e); - } - }); + $native_connection->sqliteCreateFunction('REGEXP', $this->regexp(...), 2); + $native_connection->sqliteCreateFunction('FIELD', $this->field(...)); } } } + + /** + * This function emulates the MySQL regexp function for SQLite + * @param string $pattern + * @param string $value + * @return int + */ + private function regexp(string $pattern, string $value): int + { + try { + return (mb_ereg($pattern, $value)) ? 1 : 0; + } catch (\ErrorException $e) { + throw InvalidRegexException::fromMBRegexError($e); + } + } + + /** + * This function emulates the MySQL field function for SQLite + * This function returns the index (position) of the first argument in the subsequent arguments.# + * If the first argument is not found or is NULL, 0 is returned. + * @param string|int|null $value + * @param mixed ...$array + * @return int + */ + private function field(string|int|null $value, ...$array): int + { + if ($value === null) { + return 0; + } + + //We are loose with the types here + $index = array_search($value, $array, false); + + if ($index === false) { + return 0; + } + + return $index + 1; + } } diff --git a/src/Repository/AttachmentContainingDBElementRepository.php b/src/Repository/AttachmentContainingDBElementRepository.php index de4d61cb..267982a1 100644 --- a/src/Repository/AttachmentContainingDBElementRepository.php +++ b/src/Repository/AttachmentContainingDBElementRepository.php @@ -56,13 +56,14 @@ class AttachmentContainingDBElementRepository extends NamedDBElementRepository $qb = $this->createQueryBuilder('element'); $q = $qb->select('element') ->where('element.id IN (?1)') + //Order the results in the same order as the IDs in the input array (mysql supports this native, for SQLite we emulate it) + ->orderBy('FIELD(element.id, ?1)') ->setParameter(1, $ids) ->getQuery(); $q->setFetchMode($this->getEntityName(), 'master_picture_attachment', ClassMetadataInfo::FETCH_EAGER); $result = $q->getResult(); - $this->sortResultArrayByIDArray($result, $ids); //Cache the result $this->elementsAndPreviewAttachmentCache[$cache_key] = $result; diff --git a/src/Repository/DBElementRepository.php b/src/Repository/DBElementRepository.php index 534f3963..26bcb7a8 100644 --- a/src/Repository/DBElementRepository.php +++ b/src/Repository/DBElementRepository.php @@ -113,13 +113,12 @@ class DBElementRepository extends EntityRepository $q = $qb->select('element') ->where('element.id IN (?1)') ->setParameter(1, $ids) + //Order the results in the same order as the IDs in the input array (mysql supports this native, for SQLite we emulate it) + ->orderBy('FIELD(element.id, ?1)') ->getQuery(); $result = $q->getResult(); - //Sort the result so that the elements are in the same order as the input array - $this->sortResultArrayByIDArray($result, $ids); - //Cache the result $this->find_elements_by_id_cache[$cache_key] = $result;