mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-16 23:39:54 +03:00
Ensure ordering by title is consistent between database engines
This commit is contained in:
parent
7f4137e7cc
commit
90514c603f
3 changed files with 19 additions and 15 deletions
|
@ -124,15 +124,15 @@
|
||||||
"test:db": "@parallel test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms",
|
"test:db": "@parallel test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms",
|
||||||
"test:db:sqlite": "APP_ENV=test php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-db.xml",
|
"test:db:sqlite": "APP_ENV=test php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-db.xml",
|
||||||
"test:db:sqlite:ci": "@test:db:sqlite --coverage-php build/coverage-db.cov",
|
"test:db:sqlite:ci": "@test:db:sqlite --coverage-php build/coverage-db.cov",
|
||||||
"test:db:mysql": "DB_DRIVER=mysql composer test:db:sqlite",
|
"test:db:mysql": "DB_DRIVER=mysql composer test:db:sqlite -- $*",
|
||||||
"test:db:maria": "DB_DRIVER=maria composer test:db:sqlite",
|
"test:db:maria": "DB_DRIVER=maria composer test:db:sqlite -- $*",
|
||||||
"test:db:postgres": "DB_DRIVER=postgres composer test:db:sqlite",
|
"test:db:postgres": "DB_DRIVER=postgres composer test:db:sqlite -- $*",
|
||||||
"test:db:ms": "DB_DRIVER=mssql composer test:db:sqlite",
|
"test:db:ms": "DB_DRIVER=mssql composer test:db:sqlite -- $*",
|
||||||
"test:api": "bin/test/run-api-tests.sh",
|
"test:api": "bin/test/run-api-tests.sh",
|
||||||
"test:api:sqlite": "DB_DRIVER=sqlite composer test:api",
|
"test:api:sqlite": "DB_DRIVER=sqlite composer test:api -- $*",
|
||||||
"test:api:mysql": "DB_DRIVER=mysql composer test:api",
|
"test:api:mysql": "DB_DRIVER=mysql composer test:api -- $*",
|
||||||
"test:api:maria": "DB_DRIVER=maria composer test:api",
|
"test:api:maria": "DB_DRIVER=maria composer test:api -- $*",
|
||||||
"test:api:mssql": "DB_DRIVER=mssql composer test:api",
|
"test:api:mssql": "DB_DRIVER=mssql composer test:api -- $*",
|
||||||
"test:api:ci": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --php build/coverage-api.cov && rm build/coverage-api/*.cov",
|
"test:api:ci": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --php build/coverage-api.cov && rm build/coverage-api/*.cov",
|
||||||
"test:api:pretty": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --html build/coverage-api/coverage-html && rm build/coverage-api/*.cov",
|
"test:api:pretty": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --html build/coverage-api/coverage-html && rm build/coverage-api/*.cov",
|
||||||
"test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml",
|
"test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml",
|
||||||
|
|
|
@ -46,6 +46,8 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements Sh
|
||||||
'DISTINCT s AS shortUrl',
|
'DISTINCT s AS shortUrl',
|
||||||
'(' . $buildVisitsSubQuery('v', excludingBots: false) . ') AS ' . OrderableField::VISITS->value,
|
'(' . $buildVisitsSubQuery('v', excludingBots: false) . ') AS ' . OrderableField::VISITS->value,
|
||||||
'(' . $buildVisitsSubQuery('v2', excludingBots: true) . ') AS ' . OrderableField::NON_BOT_VISITS->value,
|
'(' . $buildVisitsSubQuery('v2', excludingBots: true) . ') AS ' . OrderableField::NON_BOT_VISITS->value,
|
||||||
|
// This is added only to have a consistent order by title between database engines
|
||||||
|
'COALESCE(s.title, \'\') AS title',
|
||||||
)
|
)
|
||||||
->setMaxResults($filtering->limit)
|
->setMaxResults($filtering->limit)
|
||||||
->setFirstResult($filtering->offset)
|
->setFirstResult($filtering->offset)
|
||||||
|
@ -62,15 +64,17 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements Sh
|
||||||
private function processOrderByForList(QueryBuilder $qb, ShortUrlsListFiltering $filtering): void
|
private function processOrderByForList(QueryBuilder $qb, ShortUrlsListFiltering $filtering): void
|
||||||
{
|
{
|
||||||
$fieldName = $filtering->orderBy->field;
|
$fieldName = $filtering->orderBy->field;
|
||||||
$order = $filtering->orderBy->direction;
|
$direction = $filtering->orderBy->direction;
|
||||||
|
[$sort, $order] = match (true) {
|
||||||
match (true) {
|
|
||||||
// With no explicit order by, fallback to dateCreated-DESC
|
// With no explicit order by, fallback to dateCreated-DESC
|
||||||
$fieldName === null => $qb->orderBy('s.dateCreated', 'DESC'),
|
$fieldName === null => ['s.dateCreated', 'DESC'],
|
||||||
$fieldName === OrderableField::VISITS->value,
|
$fieldName === OrderableField::VISITS->value,
|
||||||
$fieldName === OrderableField::NON_BOT_VISITS->value => $qb->orderBy($fieldName, $order),
|
$fieldName === OrderableField::NON_BOT_VISITS->value,
|
||||||
default => $qb->orderBy('s.' . $fieldName, $order),
|
$fieldName === OrderableField::TITLE->value => [$fieldName, $direction],
|
||||||
|
default => ['s.' . $fieldName, $direction],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$qb->orderBy($sort, $order);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countList(ShortUrlsCountFiltering $filtering): int
|
public function countList(ShortUrlsCountFiltering $filtering): int
|
||||||
|
|
|
@ -201,12 +201,12 @@ class ListShortUrlsTest extends ApiTestCase
|
||||||
self::SHORT_URL_SHLINK_WITH_TITLE,
|
self::SHORT_URL_SHLINK_WITH_TITLE,
|
||||||
], 'valid_api_key'];
|
], 'valid_api_key'];
|
||||||
yield [['orderBy' => 'title-DESC'], [
|
yield [['orderBy' => 'title-DESC'], [
|
||||||
|
self::SHORT_URL_SHLINK_WITH_TITLE,
|
||||||
self::SHORT_URL_META,
|
self::SHORT_URL_META,
|
||||||
self::SHORT_URL_CUSTOM_SLUG,
|
self::SHORT_URL_CUSTOM_SLUG,
|
||||||
self::SHORT_URL_DOCS,
|
self::SHORT_URL_DOCS,
|
||||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||||
self::SHORT_URL_CUSTOM_SLUG_AND_DOMAIN,
|
self::SHORT_URL_CUSTOM_SLUG_AND_DOMAIN,
|
||||||
self::SHORT_URL_SHLINK_WITH_TITLE,
|
|
||||||
], 'valid_api_key'];
|
], 'valid_api_key'];
|
||||||
yield [['startDate' => Chronos::parse('2018-12-01')->toAtomString()], [
|
yield [['startDate' => Chronos::parse('2018-12-01')->toAtomString()], [
|
||||||
self::SHORT_URL_CUSTOM_DOMAIN,
|
self::SHORT_URL_CUSTOM_DOMAIN,
|
||||||
|
|
Loading…
Add table
Reference in a new issue