Changes for RC1 #6
|
@ -143,6 +143,44 @@ class Query
|
||||||
return "UPDATE $tableName SET data = :data WHERE " . self::whereById();
|
return "UPDATE $tableName SET data = :data WHERE " . self::whereById();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a field to an ORDER BY clause segment
|
||||||
|
*
|
||||||
|
* @param Field $field The field by which ordering should be implemented
|
||||||
|
* @return string The ORDER BY fragment for the given field
|
||||||
|
* @throws Exception If the database mode has not been set
|
||||||
|
*/
|
||||||
|
private static function mapToOrderBy(Field $field): string
|
||||||
|
{
|
||||||
|
$mode = Configuration::mode('render ORDER BY clause');
|
||||||
|
|
||||||
|
if (str_contains($field->fieldName, ' ')) {
|
||||||
|
$parts = explode(' ', $field->fieldName);
|
||||||
|
$field->fieldName = array_shift($parts);
|
||||||
|
$direction = ' ' . implode(' ', $parts);
|
||||||
|
} else {
|
||||||
|
$direction = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_starts_with($field->fieldName, 'n:')) {
|
||||||
|
$field->fieldName = substr($field->fieldName, 2);
|
||||||
|
$value = match ($mode) {
|
||||||
|
Mode::PgSQL => '(' . $field->path() . ')::numeric',
|
||||||
|
Mode::SQLite => $field->path()
|
||||||
|
};
|
||||||
|
} elseif (str_starts_with($field->fieldName, 'i:')) {
|
||||||
|
$field->fieldName = substr($field->fieldName, 2);
|
||||||
|
$value = match ($mode) {
|
||||||
|
Mode::PgSQL => 'LOWER(' . $field->path() . ')',
|
||||||
|
Mode::SQLite => $field->path() . ' COLLATE NOCASE'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$value = $field->path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (empty($field->qualifier) ? '' : "$field->qualifier.") . $value . $direction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an `ORDER BY` clause ('n:' treats field as number, 'i:' does case-insensitive ordering)
|
* Create an `ORDER BY` clause ('n:' treats field as number, 'i:' does case-insensitive ordering)
|
||||||
*
|
*
|
||||||
|
@ -152,36 +190,6 @@ class Query
|
||||||
*/
|
*/
|
||||||
public static function orderBy(array $fields): string
|
public static function orderBy(array $fields): string
|
||||||
{
|
{
|
||||||
if (empty($fields)) return "";
|
return empty($fields) ? "" : ' ORDER BY ' . implode(', ', array_map(self::mapToOrderBy(...), $fields));
|
||||||
|
|
||||||
$mode = Configuration::mode('render ORDER BY clause');
|
|
||||||
$sqlFields = array_map(function (Field $it) use ($mode) {
|
|
||||||
if (str_contains($it->fieldName, ' ')) {
|
|
||||||
$parts = explode(' ', $it->fieldName);
|
|
||||||
$it->fieldName = array_shift($parts);
|
|
||||||
$direction = ' ' . implode(' ', $parts);
|
|
||||||
} else {
|
|
||||||
$direction = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_starts_with($it->fieldName, 'n:')) {
|
|
||||||
$it->fieldName = substr($it->fieldName, 2);
|
|
||||||
$value = match ($mode) {
|
|
||||||
Mode::PgSQL => '(' . $it->path() . ')::numeric',
|
|
||||||
Mode::SQLite => $it->path()
|
|
||||||
};
|
|
||||||
} elseif (str_starts_with($it->fieldName, 'i:')) {
|
|
||||||
$it->fieldName = substr($it->fieldName, 2);
|
|
||||||
$value = match ($mode) {
|
|
||||||
Mode::PgSQL => 'LOWER(' . $it->path() . ')',
|
|
||||||
Mode::SQLite => $it->path() . ' COLLATE NOCASE'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
$value = $it->path();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value . $direction;
|
|
||||||
}, $fields);
|
|
||||||
return ' ORDER BY ' . implode(', ', $sqlFields);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,25 @@ class QueryTest extends TestCase
|
||||||
'ORDER BY not constructed correctly');
|
'ORDER BY not constructed correctly');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[TestDox('orderBy() succeeds with one qualified field for PostgreSQL')]
|
||||||
|
public function testOrderBySucceedsWithOneQualifiedFieldForPostgreSQL(): void
|
||||||
|
{
|
||||||
|
Configuration::overrideMode(Mode::PgSQL);
|
||||||
|
$field = Field::named('TestField');
|
||||||
|
$field->qualifier = 'qual';
|
||||||
|
$this->assertEquals(" ORDER BY qual.data->>'TestField'", Query::orderBy([$field]),
|
||||||
|
'ORDER BY not constructed correctly');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[TestDox('orderBy() succeeds with one qualified field for SQLite')]
|
||||||
|
public function testOrderBySucceedsWithOneQualifiedFieldForSQLite(): void
|
||||||
|
{
|
||||||
|
$field = Field::named('TestField');
|
||||||
|
$field->qualifier = 'qual';
|
||||||
|
$this->assertEquals(" ORDER BY qual.data->>'TestField'", Query::orderBy([$field]),
|
||||||
|
'ORDER BY not constructed correctly');
|
||||||
|
}
|
||||||
|
|
||||||
#[TestDox('orderBy() succeeds with multiple fields and direction for PostgreSQL')]
|
#[TestDox('orderBy() succeeds with multiple fields and direction for PostgreSQL')]
|
||||||
public function testOrderBySucceedsWithMultipleFieldsAndDirectionForPostgreSQL(): void
|
public function testOrderBySucceedsWithMultipleFieldsAndDirectionForPostgreSQL(): void
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user