From a3df029c10b2cef5dac5e2d427d87ee1326d2bd7 Mon Sep 17 00:00:00 2001 From: Chris Lloyd Date: Thu, 18 Mar 2021 16:43:48 +0000 Subject: [PATCH] Fix applying query options to entity sets --- ...lat3-Lodata-Drivers-EloquentEntitySet.html | 359 ++++++++++++++++-- .../Flat3-Lodata-Drivers-SQL-SQLSchema.html | 8 +- .../Flat3-Lodata-Drivers-SQLEntitySet.html | 337 ++++++++++++++-- docs/classes/Flat3-Lodata-EntitySet.html | 339 +++++++++++++++-- .../Flat3-Lodata-Expression-Lexer.html | 14 +- ...Flat3-Lodata-Expression-Parser-Filter.html | 24 +- ...Flat3-Lodata-Expression-Parser-Search.html | 24 +- .../Flat3-Lodata-Expression-Parser.html | 26 +- docs/js/searchIndex.js | 43 ++- docs/packages/Flat3.html | 5 +- src/Drivers/EloquentEntitySet.php | 2 +- src/Drivers/SQL/SQLOrderBy.php | 2 +- src/Drivers/SQL/SQLWhere.php | 4 +- src/Drivers/SQLEntitySet.php | 2 +- src/Entity.php | 6 +- src/EntitySet.php | 82 +++- tests/Unit/Queries/Expand/ExpandTest.php | 14 +- ...ith_expand_select_multiple_and_top__2.json | 9 + .../Queries/Navigation/NavigationTest.php | 25 ++ ...y_query_parameters_to_last_segment__1.json | 14 + 20 files changed, 1183 insertions(+), 156 deletions(-) create mode 100644 tests/Unit/Queries/Expand/__snapshots__/ExpandTest__test_select_with_expand_select_multiple_and_top__2.json create mode 100644 tests/Unit/Queries/Navigation/NavigationTest.php create mode 100644 tests/Unit/Queries/Navigation/__snapshots__/NavigationTest__test_apply_query_parameters_to_last_segment__1.json diff --git a/docs/classes/Flat3-Lodata-Drivers-EloquentEntitySet.html b/docs/classes/Flat3-Lodata-Drivers-EloquentEntitySet.html index f69a2522b..55cc268b8 100644 --- a/docs/classes/Flat3-Lodata-Drivers-EloquentEntitySet.html +++ b/docs/classes/Flat3-Lodata-Drivers-EloquentEntitySet.html @@ -301,6 +301,13 @@

Get the context URL for this entity set instance
+
+ getCount() + +  : Count +
+
Return the count option that applies to this entity set
+
getDriver() @@ -308,6 +315,13 @@

Get the PDO driver name
+
+ getFilter() + +  : Filter +
+
Return the filter option that applies to this entity set
+
getHandle() @@ -357,6 +371,13 @@

Get the navigation bindings attached to this entity set
+
+ getOrderBy() + +  : OrderBy +
+
Return the orderby option that applies to this entity set
+
getResolvedName() @@ -371,6 +392,20 @@

Get the resource URL for this entity set instance
+
+ getSearch() + +  : Search +
+
Return the search option that applies to this entity set
+ +
+ getSelect() + +  : Select +
+
Return this select option that applies to this entity set
+
getSetName() @@ -378,6 +413,13 @@

Get the OData entity set name for this Eloquent model
+
+ getSkip() + +  : Skip +
+
Return the skip option that applies to this entity set
+
getTable() @@ -392,6 +434,13 @@

Get the title
+
+ getTop() + +  : Top +
+
Return the top option that applies to this entity set
+
getTransaction() @@ -765,7 +814,7 @@

Add a navigation binding to this entity set

@@ -811,7 +860,7 @@

Count the number of results in the result buffer

@@ -845,7 +894,7 @@

Create an Eloquent model

@@ -880,7 +929,7 @@

The current entity in the results buffer

@@ -915,7 +964,7 @@

Delete an Eloquent model

@@ -961,7 +1010,7 @@

Create an entity set from the provided Eloquent model class and add it to the model

@@ -1007,7 +1056,7 @@

Discover SQL fields on this entity set as OData properties

@@ -1041,7 +1090,7 @@

Discover an Eloquent relationship method and add it to the model

@@ -1087,7 +1136,7 @@

Emit this item to the client response

@@ -1182,7 +1231,7 @@

Generate a new entity set definition

@@ -1298,7 +1347,7 @@

Read this entity set

@@ -1354,7 +1403,7 @@

EntitySet.php : - 281 + 289

Get the navigation binding for the provided navigation property on this entity set

@@ -1401,7 +1450,7 @@

Get the SQL type casts defined on this Eloquent model

@@ -1506,7 +1555,7 @@

Get the context URL for this entity set instance

@@ -1539,6 +1588,40 @@

Return values
+ +
+

+ getCount() + +

+ + +

Return the count option that applies to this entity set

+ + + public + getCount() : Count + +
+ + + + +
Return values
+ Count + — +
+ +
Return values

+ +
+

+ getFilter() + +

+ + +

Return the filter option that applies to this entity set

+ + + public + getFilter() : Filter + +
+ + + + +
Return values
+ Filter + — +
+ +

Get the OData kind of this resource

@@ -1810,7 +1927,7 @@

Get the navigation bindings attached to this entity set

@@ -1830,6 +1947,40 @@

Return values
+
+
+

+ getOrderBy() + +

+ + +

Return the orderby option that applies to this entity set

+ + + public + getOrderBy() : OrderBy + +
+ + + + +
Return values
+ OrderBy + — +
+ +

Get the resource URL for this entity set instance

@@ -1923,6 +2074,74 @@
Return values
+
+
+

+ getSearch() + +

+ + +

Return the search option that applies to this entity set

+ + + public + getSearch() : Search + +
+ + + + +
Return values
+ Search + — +
+ + +
+
+

+ getSelect() + +

+ + +

Return this select option that applies to this entity set

+ + + public + getSelect() : Select + +
+ + + + +
Return values
+ Select + — +
+ +
Return values +
+
+

+ getSkip() + +

+ + +

Return the skip option that applies to this entity set

+ + + public + getSkip() : Skip + +
+ + + + +
Return values
+ Skip + — +
+ +

Get the database table name used by the model

@@ -2039,6 +2292,40 @@
Return values
+
+
+

+ getTop() + +

+ + +

Return the top option that applies to this entity set

+ + + public + getTop() : Top + +
+ + + + +
Return values
+ Top + — +
+ +

Get the entity type of this entity set

@@ -2170,7 +2457,7 @@

Get the entity ID of the current entity in the results buffer

@@ -2205,7 +2492,7 @@

Convert an Eloquent model instance to an OData Entity

@@ -2252,7 +2539,7 @@

Generate a new entity attached to this entity set instance

@@ -2287,7 +2574,7 @@

Move to the next entity in the results buffer

@@ -2321,7 +2608,7 @@

Path component handler

@@ -2395,7 +2682,7 @@

Convert an entity type property to a database field

@@ -2442,7 +2729,7 @@

Query eloquent models

@@ -2477,7 +2764,7 @@

Read an Eloquent model

@@ -2524,7 +2811,7 @@

Get the entity ID of the entity this set was generated from using the attached expansion property value

@@ -2559,7 +2846,7 @@

Generate the client response

@@ -2615,7 +2902,7 @@

Rewind the results buffer

@@ -2741,7 +3028,7 @@

Get the expansion property value that generated this entity set instance

@@ -2833,7 +3120,7 @@

Set the maximum pagination size to use with the service providing results into the buffer

@@ -3017,7 +3304,7 @@

Set the entity type of this entity set

@@ -3063,7 +3350,7 @@

Convert an SQL type to an OData primitive type

@@ -3110,7 +3397,7 @@

Update an Eloquent model

@@ -3236,7 +3523,7 @@

Whether there is a current entity in the results buffer diff --git a/docs/classes/Flat3-Lodata-Drivers-SQL-SQLSchema.html b/docs/classes/Flat3-Lodata-Drivers-SQL-SQLSchema.html index 0b070a53b..8255d116c 100644 --- a/docs/classes/Flat3-Lodata-Drivers-SQL-SQLSchema.html +++ b/docs/classes/Flat3-Lodata-Drivers-SQL-SQLSchema.html @@ -95,7 +95,7 @@

SQL Schema

@@ -160,7 +160,7 @@

Discover SQL fields on this entity set as OData properties

@@ -194,7 +194,7 @@

Get list of defined type casts

@@ -229,7 +229,7 @@

Convert an SQL type to an OData primitive type

diff --git a/docs/classes/Flat3-Lodata-Drivers-SQLEntitySet.html b/docs/classes/Flat3-Lodata-Drivers-SQLEntitySet.html index 9d622b116..6fba17bc5 100644 --- a/docs/classes/Flat3-Lodata-Drivers-SQLEntitySet.html +++ b/docs/classes/Flat3-Lodata-Drivers-SQLEntitySet.html @@ -319,6 +319,13 @@

Get the context URL for this entity set instance
+
+ getCount() + +  : Count +
+
Return the count option that applies to this entity set
+
getDriver() @@ -326,6 +333,13 @@

Get the PDO driver name
+
+ getFilter() + +  : Filter +
+
Return the filter option that applies to this entity set
+
getHandle() @@ -368,6 +382,13 @@

Get the navigation bindings attached to this entity set
+
+ getOrderBy() + +  : OrderBy +
+
Return the orderby option that applies to this entity set
+
getPropertySourceName() @@ -396,6 +417,20 @@

Get a version of the query string that counts the total number of rows in the collection
+
+ getSearch() + +  : Search +
+
Return the search option that applies to this entity set
+ +
+ getSelect() + +  : Select +
+
Return this select option that applies to this entity set
+
getSetResultQueryString() @@ -403,6 +438,13 @@

Get the query string representing the query result
+
+ getSkip() + +  : Skip +
+
Return the skip option that applies to this entity set
+
getTable() @@ -417,6 +459,13 @@

Get the title
+
+ getTop() + +  : Top +
+
Return the top option that applies to this entity set
+
getTransaction() @@ -818,7 +867,7 @@

Add a navigation binding to this entity set

@@ -981,7 +1030,7 @@

The current entity in the results buffer

@@ -1062,7 +1111,7 @@

Discover SQL fields on this entity set as OData properties

@@ -1096,7 +1145,7 @@

Emit this item to the client response

@@ -1191,7 +1240,7 @@

Generate a new entity set definition

@@ -1411,7 +1460,7 @@

Read this entity set

@@ -1467,7 +1516,7 @@

EntitySet.php : - 281 + 289

Get the navigation binding for the provided navigation property on this entity set

@@ -1514,7 +1563,7 @@

Get list of defined type casts

@@ -1619,7 +1668,7 @@

Get the context URL for this entity set instance

@@ -1652,6 +1701,40 @@

Return values
+

+
+

+ getCount() + +

+ + +

Return the count option that applies to this entity set

+ + + public + getCount() : Count + +
+ + + + +
Return values
+ Count + — +
+ +
Return values +
+
+

+ getFilter() + +

+ + +

Return the filter option that applies to this entity set

+ + + public + getFilter() : Filter + +
+ + + + +
Return values
+ Filter + — +
+ +

Get the OData kind of this resource

@@ -1876,7 +1993,7 @@

Get the navigation bindings attached to this entity set

@@ -1896,6 +2013,40 @@

Return values
+
+
+

+ getOrderBy() + +

+ + +

Return the orderby option that applies to this entity set

+ + + public + getOrderBy() : OrderBy + +
+ + + + +
Return values
+ OrderBy + — +
+ +

Get the resource URL for this entity set instance

@@ -2071,6 +2222,74 @@
Return values
+
+
+

+ getSearch() + +

+ + +

Return the search option that applies to this entity set

+ + + public + getSearch() : Search + +
+ + + + +
Return values
+ Search + — +
+ + +
+
+

+ getSelect() + +

+ + +

Return this select option that applies to this entity set

+ + + public + getSelect() : Select + +
+ + + + +
Return values
+ Select + — +
+ +
Return values +
+
+

+ getSkip() + +

+ + +

Return the skip option that applies to this entity set

+ + + public + getSkip() : Skip + +
+ + + + +
Return values
+ Skip + — +
+ +
Return values
+
+
+

+ getTop() + +

+ + +

Return the top option that applies to this entity set

+ + + public + getTop() : Top + +
+ + + + +
Return values
+ Top + — +
+ +

Get the entity type of this entity set

@@ -2259,7 +2546,7 @@

Get the entity ID of the current entity in the results buffer

@@ -2294,7 +2581,7 @@

Generate a new entity attached to this entity set instance

@@ -2329,7 +2616,7 @@

Move to the next entity in the results buffer

@@ -2363,7 +2650,7 @@

Path component handler

@@ -2519,7 +2806,7 @@

Get the entity ID of the entity this set was generated from using the attached expansion property value

@@ -2554,7 +2841,7 @@

Generate the client response

@@ -2610,7 +2897,7 @@

Rewind the results buffer

@@ -2736,7 +3023,7 @@

Get the expansion property value that generated this entity set instance

@@ -2828,7 +3115,7 @@

Set the maximum pagination size to use with the service providing results into the buffer

@@ -3012,7 +3299,7 @@

Set the entity type of this entity set

@@ -3058,7 +3345,7 @@

Convert an SQL type to an OData primitive type

@@ -3231,7 +3518,7 @@

Whether there is a current entity in the results buffer diff --git a/docs/classes/Flat3-Lodata-EntitySet.html b/docs/classes/Flat3-Lodata-EntitySet.html index 7847b63b4..19c338631 100644 --- a/docs/classes/Flat3-Lodata-EntitySet.html +++ b/docs/classes/Flat3-Lodata-EntitySet.html @@ -103,7 +103,7 @@

Entity Set

@@ -251,6 +251,20 @@

Get the context URL for this entity set instance
+
+ getCount() + +  : Count +
+
Return the count option that applies to this entity set
+ +
+ getFilter() + +  : Filter +
+
Return the filter option that applies to this entity set
+
getIdentifier() @@ -286,6 +300,13 @@

Get the navigation bindings attached to this entity set
+
+ getOrderBy() + +  : OrderBy +
+
Return the orderby option that applies to this entity set
+
getResolvedName() @@ -300,6 +321,27 @@

Get the resource URL for this entity set instance
+
+ getSearch() + +  : Search +
+
Return the search option that applies to this entity set
+ +
+ getSelect() + +  : Select +
+
Return this select option that applies to this entity set
+ +
+ getSkip() + +  : Skip +
+
Return the skip option that applies to this entity set
+
getTitle() @@ -307,6 +349,13 @@

Get the title
+
+ getTop() + +  : Top +
+
Return the top option that applies to this entity set
+
getTransaction() @@ -547,7 +596,7 @@

@@ -596,7 +645,7 @@

Add a navigation binding to this entity set

@@ -642,7 +691,7 @@

Count the number of results in the result buffer

@@ -676,7 +725,7 @@

The current entity in the results buffer

@@ -711,7 +760,7 @@

Emit this item to the client response

@@ -806,7 +855,7 @@

Generate a new entity set definition

@@ -876,7 +925,7 @@

Read this entity set

@@ -932,7 +981,7 @@

EntitySet.php : - 281 + 289

Get the navigation binding for the provided navigation property on this entity set

@@ -979,7 +1028,7 @@

Get the context URL for this entity set instance

@@ -1012,6 +1061,74 @@

Return values
+

+
+

+ getCount() + +

+ + +

Return the count option that applies to this entity set

+ + + public + getCount() : Count + +
+ + + + +
Return values
+ Count + — +
+ + +
+
+

+ getFilter() + +

+ + +

Return the filter option that applies to this entity set

+ + + public + getFilter() : Filter + +
+ + + + +
Return values
+ Filter + — +
+ +

Get the OData kind of this resource

@@ -1166,7 +1283,7 @@

Get the navigation bindings attached to this entity set

@@ -1186,6 +1303,40 @@

Return values
+
+
+

+ getOrderBy() + +

+ + +

Return the orderby option that applies to this entity set

+ + + public + getOrderBy() : OrderBy + +
+ + + + +
Return values
+ OrderBy + — +
+ +

Get the resource URL for this entity set instance

@@ -1279,6 +1430,108 @@
Return values
+
+
+

+ getSearch() + +

+ + +

Return the search option that applies to this entity set

+ + + public + getSearch() : Search + +
+ + + + +
Return values
+ Search + — +
+ + +
+
+

+ getSelect() + +

+ + +

Return this select option that applies to this entity set

+ + + public + getSelect() : Select + +
+ + + + +
Return values
+ Select + — +
+ + +
+
+

+ getSkip() + +

+ + +

Return the skip option that applies to this entity set

+ + + public + getSkip() : Skip + +
+ + + + +
Return values
+ Skip + — +
+ +
Return values
+
+
+

+ getTop() + +

+ + +

Return the top option that applies to this entity set

+ + + public + getTop() : Top + +
+ + + + +
Return values
+ Top + — +
+ +

Get the entity type of this entity set

@@ -1397,7 +1684,7 @@

Get the entity ID of the current entity in the results buffer

@@ -1432,7 +1719,7 @@

Generate a new entity attached to this entity set instance

@@ -1467,7 +1754,7 @@

Move to the next entity in the results buffer

@@ -1501,7 +1788,7 @@

Path component handler

@@ -1575,7 +1862,7 @@

Get the entity ID of the entity this set was generated from using the attached expansion property value

@@ -1610,7 +1897,7 @@

Generate the client response

@@ -1666,7 +1953,7 @@

Rewind the results buffer

@@ -1700,7 +1987,7 @@

Get the expansion property value that generated this entity set instance

@@ -1792,7 +2079,7 @@

Set the maximum pagination size to use with the service providing results into the buffer

@@ -1884,7 +2171,7 @@

Set the context transaction this entity set instance should use

@@ -1930,7 +2217,7 @@

Set the entity type of this entity set

@@ -2055,7 +2342,7 @@

Whether there is a current entity in the results buffer diff --git a/docs/classes/Flat3-Lodata-Expression-Lexer.html b/docs/classes/Flat3-Lodata-Expression-Lexer.html index e17698ebf..8a646584d 100644 --- a/docs/classes/Flat3-Lodata-Expression-Lexer.html +++ b/docs/classes/Flat3-Lodata-Expression-Lexer.html @@ -524,11 +524,11 @@

Sort the provided array by value length
- splitCommaSeparatedQueryString() + splitSemicolonSeparatedQueryString()  : array<string|int, mixed>
-
Split a comma separated query string
+
Split a semicolon separated query string
string_() @@ -2761,9 +2761,9 @@
Return values
-public " > -

- splitCommaSeparatedQueryString() - +

+ splitSemicolonSeparatedQueryString() +

-

Split a comma separated query string

+

Split a semicolon separated query string

public - splitCommaSeparatedQueryString() : array<string|int, mixed> + splitSemicolonSeparatedQueryString() : array<string|int, mixed>
diff --git a/docs/classes/Flat3-Lodata-Expression-Parser-Filter.html b/docs/classes/Flat3-Lodata-Expression-Parser-Filter.html index 251785753..0d460b674 100644 --- a/docs/classes/Flat3-Lodata-Expression-Parser-Filter.html +++ b/docs/classes/Flat3-Lodata-Expression-Parser-Filter.html @@ -774,7 +774,7 @@

Tokenize a boolean

@@ -843,7 +843,7 @@

Tokenize a date

@@ -877,7 +877,7 @@

Tokenize a date time offset

@@ -911,7 +911,7 @@

Tokenize a double quoted string

@@ -945,7 +945,7 @@

Tokenize a duration

@@ -979,7 +979,7 @@

Tokenize a GUID

@@ -1013,7 +1013,7 @@

Tokenize a registered literal keyword

@@ -1081,7 +1081,7 @@

Tokenize literal null

@@ -1115,7 +1115,7 @@

Tokenize a number

@@ -1263,7 +1263,7 @@

Tokenize a single quoted string

@@ -1331,7 +1331,7 @@

Tokenize a string

@@ -1365,7 +1365,7 @@

Tokenize a time of day

diff --git a/docs/classes/Flat3-Lodata-Expression-Parser-Search.html b/docs/classes/Flat3-Lodata-Expression-Parser-Search.html index a9241c130..b8d933b61 100644 --- a/docs/classes/Flat3-Lodata-Expression-Parser-Search.html +++ b/docs/classes/Flat3-Lodata-Expression-Parser-Search.html @@ -623,7 +623,7 @@

Tokenize a boolean

@@ -692,7 +692,7 @@

Tokenize a date

@@ -726,7 +726,7 @@

Tokenize a date time offset

@@ -760,7 +760,7 @@

Tokenize a double quoted string

@@ -794,7 +794,7 @@

Tokenize a duration

@@ -828,7 +828,7 @@

Tokenize a GUID

@@ -862,7 +862,7 @@

Tokenize a registered literal keyword

@@ -930,7 +930,7 @@

Tokenize literal null

@@ -964,7 +964,7 @@

Tokenize a number

@@ -1066,7 +1066,7 @@

Tokenize a single quoted string

@@ -1134,7 +1134,7 @@

Tokenize a string

@@ -1168,7 +1168,7 @@

Tokenize a time of day

diff --git a/docs/classes/Flat3-Lodata-Expression-Parser.html b/docs/classes/Flat3-Lodata-Expression-Parser.html index 1e2938864..d50ad7075 100644 --- a/docs/classes/Flat3-Lodata-Expression-Parser.html +++ b/docs/classes/Flat3-Lodata-Expression-Parser.html @@ -420,7 +420,7 @@

Dispatch an expression event

@@ -581,7 +581,7 @@

Tokenize a boolean

@@ -650,7 +650,7 @@

Tokenize a date

@@ -684,7 +684,7 @@

Tokenize a date time offset

@@ -718,7 +718,7 @@

Tokenize a double quoted string

@@ -752,7 +752,7 @@

Tokenize a duration

@@ -786,7 +786,7 @@

Tokenize a GUID

@@ -820,7 +820,7 @@

Tokenize a registered literal keyword

@@ -888,7 +888,7 @@

Tokenize literal null

@@ -922,7 +922,7 @@

Tokenize a number

@@ -1024,7 +1024,7 @@

Tokenize a single quoted string

@@ -1092,7 +1092,7 @@

Tokenize a string

@@ -1126,7 +1126,7 @@

Tokenize a time of day

diff --git a/docs/js/searchIndex.js b/docs/js/searchIndex.js index 327d146f3..6d197fbbf 100644 --- a/docs/js/searchIndex.js +++ b/docs/js/searchIndex.js @@ -1470,6 +1470,41 @@ Search.appendIndex( "name": "setType", "summary": "Set\u0020the\u0020entity\u0020type\u0020of\u0020this\u0020entity\u0020set", "url": "classes/Flat3-Lodata-EntitySet.html#method_setType" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetSearch\u0028\u0029", + "name": "getSearch", + "summary": "Return\u0020the\u0020search\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getSearch" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetFilter\u0028\u0029", + "name": "getFilter", + "summary": "Return\u0020the\u0020filter\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getFilter" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetCount\u0028\u0029", + "name": "getCount", + "summary": "Return\u0020the\u0020count\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getCount" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetOrderBy\u0028\u0029", + "name": "getOrderBy", + "summary": "Return\u0020the\u0020orderby\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getOrderBy" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetSkip\u0028\u0029", + "name": "getSkip", + "summary": "Return\u0020the\u0020skip\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getSkip" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetTop\u0028\u0029", + "name": "getTop", + "summary": "Return\u0020the\u0020top\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getTop" + }, { + "fqsen": "\\Flat3\\Lodata\\EntitySet\u003A\u003AgetSelect\u0028\u0029", + "name": "getSelect", + "summary": "Return\u0020this\u0020select\u0020option\u0020that\u0020applies\u0020to\u0020this\u0020entity\u0020set", + "url": "classes/Flat3-Lodata-EntitySet.html#method_getSelect" }, { "fqsen": "\\Flat3\\Lodata\\EntityType", "name": "EntityType", @@ -2176,10 +2211,10 @@ Search.appendIndex( "summary": "Match\u0020a\u0020string\u0020enclosed\u0020in\u0020matching\u0020parentheses", "url": "classes/Flat3-Lodata-Expression-Lexer.html#method_matchingParenthesis" }, { - "fqsen": "\\Flat3\\Lodata\\Expression\\Lexer\u003A\u003AsplitCommaSeparatedQueryString\u0028\u0029", - "name": "splitCommaSeparatedQueryString", - "summary": "Split\u0020a\u0020comma\u0020separated\u0020query\u0020string", - "url": "classes/Flat3-Lodata-Expression-Lexer.html#method_splitCommaSeparatedQueryString" + "fqsen": "\\Flat3\\Lodata\\Expression\\Lexer\u003A\u003AsplitSemicolonSeparatedQueryString\u0028\u0029", + "name": "splitSemicolonSeparatedQueryString", + "summary": "Split\u0020a\u0020semicolon\u0020separated\u0020query\u0020string", + "url": "classes/Flat3-Lodata-Expression-Lexer.html#method_splitSemicolonSeparatedQueryString" }, { "fqsen": "\\Flat3\\Lodata\\Expression\\Lexer\u003A\u003AOPEN_PAREN", "name": "OPEN_PAREN", diff --git a/docs/packages/Flat3.html b/docs/packages/Flat3.html index 6ca327f65..08bd2d199 100644 --- a/docs/packages/Flat3.html +++ b/docs/packages/Flat3.html @@ -81,10 +81,11 @@

Fil
-

Flat3

+

Packages @@ -92,7 +93,7 @@

-
Lodata
+
Lodata
diff --git a/src/Drivers/EloquentEntitySet.php b/src/Drivers/EloquentEntitySet.php index 484a102b8..3ef3fc55a 100644 --- a/src/Drivers/EloquentEntitySet.php +++ b/src/Drivers/EloquentEntitySet.php @@ -287,7 +287,7 @@ public function query(): array $builder->whereRaw($this->where, $this->parameters); } - $orderby = $this->transaction->getOrderBy(); + $orderby = $this->getOrderBy(); if ($orderby->hasValue()) { foreach ($orderby->getSortOrders() as $so) { [$literal, $direction] = $so; diff --git a/src/Drivers/SQL/SQLOrderBy.php b/src/Drivers/SQL/SQLOrderBy.php index 3475527a2..de02806bb 100644 --- a/src/Drivers/SQL/SQLOrderBy.php +++ b/src/Drivers/SQL/SQLOrderBy.php @@ -16,7 +16,7 @@ trait SQLOrderBy */ public function generateOrderBy(): string { - $orderby = $this->transaction->getOrderBy(); + $orderby = $this->getOrderBy(); if (!$orderby->hasValue()) { return ''; diff --git a/src/Drivers/SQL/SQLWhere.php b/src/Drivers/SQL/SQLWhere.php index d5b9e2318..ce3f54a6d 100644 --- a/src/Drivers/SQL/SQLWhere.php +++ b/src/Drivers/SQL/SQLWhere.php @@ -39,7 +39,7 @@ protected function generateWhere(): void $this->where = ''; if ($this instanceof FilterInterface) { - $filter = $this->transaction->getFilter(); + $filter = $this->getFilter(); if ($filter->hasValue()) { $this->whereMaybeAnd(); $validLiterals = []; @@ -56,7 +56,7 @@ protected function generateWhere(): void } if ($this instanceof SearchInterface) { - $search = $this->transaction->getSearch(); + $search = $this->getSearch(); if ($search->hasValue()) { if (!$this->getType()->getDeclaredProperties()->filter(function ($property) { return $property->isSearchable(); diff --git a/src/Drivers/SQLEntitySet.php b/src/Drivers/SQLEntitySet.php index be827905a..c48f84a81 100644 --- a/src/Drivers/SQLEntitySet.php +++ b/src/Drivers/SQLEntitySet.php @@ -313,7 +313,7 @@ public function getSetResultQueryString(): string */ protected function getColumnsToQuery(): string { - $select = $this->transaction->getSelect(); + $select = $this->getSelect(); $properties = $select->getSelectedProperties($this)->sliceByClass(DeclaredProperty::class); diff --git a/src/Entity.php b/src/Entity.php index f09c73d91..f591e196a 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -351,12 +351,12 @@ public function getExpansionMetadata(Transaction $transaction, PropertyValue $pr $count = $set->count(); - if ($transaction->getCount()->hasValue()) { + if ($set->getCount()->hasValue()) { $propertyMetadata['count'] = $count; } - $top = $transaction->getTop(); - $skip = $transaction->getSkip(); + $top = $set->getTop(); + $skip = $set->getSkip(); if ($top->hasValue() && ($top->getValue() + ($skip->getValue() ?: 0) < $count)) { $np = $transaction->getQueryParams(); diff --git a/src/EntitySet.php b/src/EntitySet.php index d913a7171..72df584cb 100644 --- a/src/EntitySet.php +++ b/src/EntitySet.php @@ -43,6 +43,7 @@ use Flat3\Lodata\Traits\UseReferences; use Flat3\Lodata\Transaction\Option; use Illuminate\Http\Request; +use Illuminate\Support\Str; use Iterator; /** @@ -120,6 +121,13 @@ abstract class EntitySet implements EntityTypeInterface, ReferenceInterface, Ide */ protected $expansionPropertyValue; + /** + * Whether to apply system query options on this entity set instance + * @var bool $applyQueryOptions + * @internal + */ + protected $applyQueryOptions = true; + public function __construct(string $identifier, EntityType $entityType) { $this->setIdentifier($identifier); @@ -357,7 +365,7 @@ public function get(Transaction $transaction, ?ContextInterface $context = null) $metadata['context'] = $context->getContextUrl($transaction); - $count = $transaction->getCount(); + $count = $this->getCount(); if (true === $count->getValue()) { $metadata['count'] = $setCount; } @@ -540,7 +548,7 @@ public function resolveExpansionKey(): PropertyValue * @param Transaction $transaction Related transaction * @return $this */ - public function setTransaction(Transaction $transaction) + public function setTransaction(Transaction $transaction): self { foreach ( [ @@ -556,7 +564,7 @@ public function setTransaction(Transaction $transaction) list ($class, $option) = $sqo; /** @var Option $option */ - if ($option->hasValue() && !is_a($this, $class, true)) { + if ($this->applyQueryOptions && $option->hasValue() && !is_a($this, $class, true)) { throw new NotImplementedException( 'system_query_option_not_implemented', sprintf('The %s system query option is not supported by this entity set', $option::param) @@ -591,6 +599,11 @@ public static function pipe( } $entitySet = clone $entitySet; + + if ($nextSegment && !Str::startsWith($nextSegment, '$')) { + $entitySet->applyQueryOptions = false; + } + $entitySet->setTransaction($transaction); if ($lexer->finished()) { @@ -702,4 +715,67 @@ public function setType(EntityType $type): self return $this; } + + /** + * Return the search option that applies to this entity set + * @return Option\Search + */ + public function getSearch(): Option\Search + { + return $this->applyQueryOptions ? $this->transaction->getSearch() : new Option\Search(); + } + + /** + * Return the filter option that applies to this entity set + * @return Option\Filter + */ + public function getFilter(): Option\Filter + { + return $this->applyQueryOptions ? $this->transaction->getFilter() : new Option\Filter(); + } + + /** + * Return the count option that applies to this entity set + * @return Option\Count + */ + public function getCount(): Option\Count + { + return $this->applyQueryOptions ? $this->transaction->getCount() : new Option\Count(); + } + + /** + * Return the orderby option that applies to this entity set + * @return Option\OrderBy + */ + public function getOrderBy(): Option\OrderBy + { + return $this->applyQueryOptions ? $this->transaction->getOrderBy() : new Option\OrderBy(); + } + + /** + * Return the skip option that applies to this entity set + * @return Option\Skip + */ + public function getSkip(): Option\Skip + { + return $this->applyQueryOptions ? $this->transaction->getSkip() : new Option\Skip(); + } + + /** + * Return the top option that applies to this entity set + * @return Option\Top + */ + public function getTop(): Option\Top + { + return $this->applyQueryOptions ? $this->transaction->getTop() : new Option\Top(); + } + + /** + * Return this select option that applies to this entity set + * @return Option\Select + */ + public function getSelect(): Option\Select + { + return $this->applyQueryOptions ? $this->transaction->getSelect() : new Option\Select(); + } } \ No newline at end of file diff --git a/tests/Unit/Queries/Expand/ExpandTest.php b/tests/Unit/Queries/Expand/ExpandTest.php index c5e16de58..d3b3b4ed0 100644 --- a/tests/Unit/Queries/Expand/ExpandTest.php +++ b/tests/Unit/Queries/Expand/ExpandTest.php @@ -93,11 +93,17 @@ public function test_select_with_expand_select_multiple() public function test_select_with_expand_select_multiple_and_top() { + $page = $this->jsonResponse( + $this->assertJsonResponse( + Request::factory() + ->path('/flights(1)') + ->query('$select', 'origin') + ->query('$expand', 'passengers($select=flight_id,name;$top=2)') + ) + ); + $this->assertJsonResponse( - Request::factory() - ->path('/flights(1)') - ->query('$select', 'origin') - ->query('$expand', 'passengers($select=flight_id,name;$top=2)') + $this->urlToReq($page->{'passengers@nextLink'}) ); } diff --git a/tests/Unit/Queries/Expand/__snapshots__/ExpandTest__test_select_with_expand_select_multiple_and_top__2.json b/tests/Unit/Queries/Expand/__snapshots__/ExpandTest__test_select_with_expand_select_multiple_and_top__2.json new file mode 100644 index 000000000..449794e85 --- /dev/null +++ b/tests/Unit/Queries/Expand/__snapshots__/ExpandTest__test_select_with_expand_select_multiple_and_top__2.json @@ -0,0 +1,9 @@ +{ + "@context": "http://localhost/odata/$metadata#flights(1)/passengers(flight_id,name)", + "value": [ + { + "flight_id": 1, + "name": "Charlie Carrot" + } + ] +} diff --git a/tests/Unit/Queries/Navigation/NavigationTest.php b/tests/Unit/Queries/Navigation/NavigationTest.php new file mode 100644 index 000000000..761ffe14c --- /dev/null +++ b/tests/Unit/Queries/Navigation/NavigationTest.php @@ -0,0 +1,25 @@ +withFlightModel(); + } + + public function test_apply_query_parameters_to_last_segment() + { + $this->assertJsonResponse( + Request::factory() + ->path('/flights(1)/passengers') + ->query('$select', 'flight_id,name') + ->query('$top', 2) + ); + } +} diff --git a/tests/Unit/Queries/Navigation/__snapshots__/NavigationTest__test_apply_query_parameters_to_last_segment__1.json b/tests/Unit/Queries/Navigation/__snapshots__/NavigationTest__test_apply_query_parameters_to_last_segment__1.json new file mode 100644 index 000000000..301e507f3 --- /dev/null +++ b/tests/Unit/Queries/Navigation/__snapshots__/NavigationTest__test_apply_query_parameters_to_last_segment__1.json @@ -0,0 +1,14 @@ +{ + "@context": "http://localhost/odata/$metadata#flights(1)/passengers(flight_id,name)", + "@nextLink": "http://localhost/odata/passengers?%24select=flight_id%2Cname&%24top=2&%24skip=2", + "value": [ + { + "flight_id": 1, + "name": "Anne Arbor" + }, + { + "flight_id": 1, + "name": "Bob Barry" + } + ] +}