Skip to content

Commit 0fafc79

Browse files
authored
Merge pull request #55 from alxsabo/v5.2
Facets field names should be escaped
2 parents fbc7cf4 + c868df8 commit 0fafc79

File tree

6 files changed

+82
-66
lines changed

6 files changed

+82
-66
lines changed

src/Documents/Indexes/Spatial/SpatialUnits.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
// !status: DONE
88
class SpatialUnits implements ValueObjectInterface
99
{
10-
private const KILOMETERS = 'kilometers';
11-
private const MILES = 'miles';
10+
private const KILOMETERS = 'Kilometers';
11+
private const MILES = 'Miles';
1212

1313
private string $value;
1414

src/Documents/Queries/QueryFieldUtil.php

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,40 @@
33
namespace RavenDB\Documents\Queries;
44

55
use RavenDB\Constants\DocumentsIndexingFields;
6+
use RavenDB\Utils\StringBuilder;
67

78
class QueryFieldUtil
89
{
910
private static function shouldEscape(string $s, bool $isPath): bool
1011
{
1112
$escape = false;
1213
$insideEscaped = false;
13-
//
14-
// for (int i = 0; i < s.length(); i++) {
15-
// char c = s.charAt(i);
16-
//
17-
// if (c == '\'' || c == '"') {
18-
// insideEscaped = !insideEscaped;
19-
// continue;
20-
// }
21-
//
22-
// if (i == 0) {
23-
// if (!Character.isLetter(c) && c != '_' && c != '@' && !insideEscaped) {
24-
// escape = true;
25-
// break;
26-
// }
27-
// } else {
28-
// if (!Character.isLetterOrDigit(c) && c != '_' && c != '-' && c != '@' && c != '.' && c != '[' && c != ']' && !insideEscaped) {
29-
// escape = true;
30-
// break;
31-
// }
32-
// if (isPath && c == '.' && !insideEscaped) {
33-
// escape = true;
34-
// break;
35-
// }
36-
// }
37-
// }
14+
15+
for ($i = 0; $i < strlen($s); $i++) {
16+
$c = $s[$i];
17+
18+
if ($c == '\'' || $c == '"') {
19+
$insideEscaped = !$insideEscaped;
20+
continue;
21+
}
22+
23+
if ($i == 0) {
24+
25+
if (!ctype_alpha($c) && $c != '_' && $c != '@' && !$insideEscaped) {
26+
$escape = true;
27+
break;
28+
}
29+
} else {
30+
if (!ctype_alnum($c) && $c != '_' && $c != '-' && $c != '@' && $c != '.' && $c != '[' && $c != ']' && !$insideEscaped) {
31+
$escape = true;
32+
break;
33+
}
34+
if ($isPath && $c == '.' && !$insideEscaped) {
35+
$escape = true;
36+
break;
37+
}
38+
}
39+
}
3840

3941
$escape |= $insideEscaped;
4042
return $escape;
@@ -56,40 +58,40 @@ public static function escapeIfNecessary(?string $name, bool $isPath = false): ?
5658
return $name;
5759
}
5860

59-
// StringBuilder sb = new StringBuilder(name);
61+
$sb = new StringBuilder($name);
6062
$needEndQuote = false;
6163
$lastTermStart = 0;
6264

63-
// for (int i = 0; i < sb.length(); i++) {
64-
// char c = sb.charAt(i);
65-
// if (i == 0 && !Character.isLetter(c) && c != '_' && c != '@') {
66-
// sb.insert(lastTermStart, '\'');
67-
// needEndQuote = true;
68-
// continue;
69-
// }
70-
//
71-
// if (isPath && c == '.') {
72-
// if (needEndQuote) {
73-
// needEndQuote = false;
74-
// sb.insert(i, '\'');
75-
// i++;
76-
// }
77-
//
78-
// lastTermStart = i + 1;
79-
// continue;
80-
// }
81-
//
82-
// if (!Character.isLetterOrDigit(c) && c != '_' && c != '-' && c != '@' && c != '.' && c != '[' && c != ']' && !needEndQuote) {
83-
// sb.insert(lastTermStart, '\'');
84-
// needEndQuote = true;
85-
// continue;
86-
// }
87-
// }
88-
//
89-
// if (needEndQuote) {
90-
// sb.append('\'');
91-
// }
92-
//
93-
// return sb.toString();
65+
for ($i = 0; $i < strlen($sb); $i++) {
66+
$c = $sb[$i];
67+
if ($i == 0 && !ctype_alpha($c) && $c != '_' && $c != '@') {
68+
$sb->insert($lastTermStart, '\'');
69+
$needEndQuote = true;
70+
continue;
71+
}
72+
73+
if ($isPath && $c == '.') {
74+
if ($needEndQuote) {
75+
$needEndQuote = false;
76+
$sb->insert($i, '\'');
77+
$i++;
78+
}
79+
80+
$lastTermStart = $i + 1;
81+
continue;
82+
}
83+
84+
if (!ctype_alnum($c) && $c != '_' && $c != '-' && $c != '@' && $c != '.' && $c != '[' && $c != ']' && !$needEndQuote) {
85+
$sb->insert($lastTermStart, '\'');
86+
$needEndQuote = true;
87+
continue;
88+
}
89+
}
90+
91+
if ($needEndQuote) {
92+
$sb->append('\'');
93+
}
94+
95+
return $sb->__toString();
9496
}
9597
}

src/Documents/Session/DocumentQuery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,10 @@ public function aggregateBy(...$builderOrFacets): AggregationDocumentQueryInterf
704704
return $this->aggregateByBuilder($builderOrFacets[0]);
705705
}
706706

707+
if (is_array($builderOrFacets[0])) {
708+
return $this->aggregateByFacets(FacetBaseArray::fromArray($builderOrFacets[0]));
709+
}
710+
707711
return $this->aggregateByFacets(FacetBaseArray::fromArray($builderOrFacets));
708712
}
709713

src/Documents/Session/Tokens/HighlightingToken.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@
77
// !status: DONE
88
class HighlightingToken extends QueryToken
99
{
10-
private string $fieldName;
10+
private ?string $fieldName = null;
1111
private int $fragmentLength;
1212
private int $fragmentCount;
13-
private string $optionsParameterName;
13+
private ?string $optionsParameterName = null;
1414

15-
private function __construct(string $fieldName, int $fragmentLength, int $fragmentCount, string $operationsParameterName)
15+
private function __construct(string $fieldName, int $fragmentLength, int $fragmentCount, ?string $operationsParameterName)
1616
{
1717
$this->fieldName = $fieldName;
1818
$this->fragmentLength = $fragmentLength;
1919
$this->fragmentCount = $fragmentCount;
2020
$this->optionsParameterName = $operationsParameterName;
2121
}
2222

23-
public static function create(string $fieldName, int $fragmentLength, int $fragmentCount, string $optionsParameterName): HighlightingToken
23+
public static function create(string $fieldName, int $fragmentLength, int $fragmentCount, ?string $optionsParameterName): HighlightingToken
2424
{
2525
return new HighlightingToken($fieldName, $fragmentLength, $fragmentCount, $optionsParameterName);
2626
}

src/Utils/StringBuilder.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ public function append(?string $value): StringBuilder
1919
return $this;
2020
}
2121

22+
public function insert(int $offset, ?string $value): StringBuilder
23+
{
24+
if ($value != null) {
25+
$oldString = $this->s;
26+
$this->s = substr($oldString, 0, $offset) . $value . substr($oldString, $offset);
27+
}
28+
29+
return $this;
30+
}
31+
2232
public function appendLine(?string $value): StringBuilder
2333
{
2434
$this->s .= PHP_EOL;

tests/Test/Server/Documents/Indexing/auto/_RavenDB_8761Test/RavenDB_8761Test.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function testCan_group_by_array_content(): void
175175
/** @var array<ProductCount> $productCounts2 */
176176
$productCounts2 = $session->advanced()
177177
->documentQuery(Order::class)
178-
->groupBy("array(lines[].product)")
178+
->groupBy(GroupBy::array("lines[].product"))
179179
->selectKey(null, "products")
180180
->selectCount()
181181
->orderBy("count")
@@ -211,7 +211,7 @@ public function testCan_group_by_array_content(): void
211211
$productCounts2 = $session
212212
->advanced()
213213
->documentQuery(Order::class)
214-
->groupBy("array(lines[].product)", GroupBy::field("shipTo.country"))
214+
->groupBy(GroupBy::array("lines[].product"), GroupBy::field("shipTo.country"))
215215
->selectKey("lines[].product", "products")
216216
->selectCount()
217217
->orderBy("count")
@@ -247,7 +247,7 @@ public function testCan_group_by_array_content(): void
247247
$productCounts2 = $session
248248
->advanced()
249249
->documentQuery(Order::class)
250-
->groupBy("array(lines[].product)", "array(lines[].quantity)")
250+
->groupBy(GroupBy::array("lines[].product"), GroupBy::array("lines[].quantity"))
251251
->selectKey("lines[].product", "products")
252252
->selectKey("lines[].quantity", "quantities")
253253
->selectCount()

0 commit comments

Comments
 (0)