Changes for RC1 #6
|
@ -17,9 +17,9 @@
|
||||||
"rss": "https://git.bitbadger.solutions/bit-badger/pdo-document.rss",
|
"rss": "https://git.bitbadger.solutions/bit-badger/pdo-document.rss",
|
||||||
"docs": "https://bitbadger.solutions/open-source/pdo-document/"
|
"docs": "https://bitbadger.solutions/open-source/pdo-document/"
|
||||||
},
|
},
|
||||||
"minimum-stability": "beta",
|
"minimum-stability": "RC",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.2",
|
"php": "8.2 - 8.3",
|
||||||
"bit-badger/inspired-by-fsharp": "^1",
|
"bit-badger/inspired-by-fsharp": "^1",
|
||||||
"netresearch/jsonmapper": "^4",
|
"netresearch/jsonmapper": "^4",
|
||||||
"ext-pdo": "*"
|
"ext-pdo": "*"
|
||||||
|
|
26
composer.lock
generated
26
composer.lock
generated
|
@ -4,18 +4,18 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "7f9c6e825e6f0968b2dedefec770f558",
|
"content-hash": "ec1fce1531c57de8cb1300e3d1cf2a83",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bit-badger/inspired-by-fsharp",
|
"name": "bit-badger/inspired-by-fsharp",
|
||||||
"version": "v1.0.0-beta2",
|
"version": "v1.0.0-rc1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp",
|
"url": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp",
|
||||||
"reference": "fad428a4e40b606987499b17bb2d5b7d4b04502d"
|
"reference": "6779b2c554cf52e2eea4bd0575ea308e4ac09570"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2"
|
"php": "8.2 - 8.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpoption/phpoption": "^1",
|
"phpoption/phpoption": "^1",
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
"rss": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp.rss",
|
"rss": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp.rss",
|
||||||
"source": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp"
|
"source": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp"
|
||||||
},
|
},
|
||||||
"time": "2024-07-29T17:58:33+00:00"
|
"time": "2024-10-01T00:14:52+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "netresearch/jsonmapper",
|
"name": "netresearch/jsonmapper",
|
||||||
|
@ -166,16 +166,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v5.2.0",
|
"version": "v5.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb"
|
"reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a",
|
||||||
"reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb",
|
"reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -218,9 +218,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0"
|
||||||
},
|
},
|
||||||
"time": "2024-09-15T16:40:33+00:00"
|
"time": "2024-09-29T13:56:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phar-io/manifest",
|
"name": "phar-io/manifest",
|
||||||
|
@ -1844,12 +1844,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "beta",
|
"minimum-stability": "RC",
|
||||||
"stability-flags": [],
|
"stability-flags": [],
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": ">=8.2",
|
"php": "8.2 - 8.3",
|
||||||
"ext-pdo": "*"
|
"ext-pdo": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
|
|
|
@ -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