Skip to content

Commit

Permalink
PHPORM-209 Add query builder helper to set read preference (#3244)
Browse files Browse the repository at this point in the history
* PHPORM-209 Add query builder helper to set read preference
* Support query timeout as decimal number of seconds
  • Loading branch information
GromNaN authored Jan 14, 2025
1 parent 8829052 commit 697c36f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
31 changes: 28 additions & 3 deletions src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use MongoDB\Builder\Type\QueryInterface;
use MongoDB\Builder\Type\SearchOperatorInterface;
use MongoDB\Driver\Cursor;
use MongoDB\Driver\ReadPreference;
use Override;
use RuntimeException;
use stdClass;
Expand Down Expand Up @@ -102,7 +103,7 @@ class Builder extends BaseBuilder
/**
* The maximum amount of seconds to allow the query to run.
*
* @var int
* @var int|float
*/
public $timeout;

Expand All @@ -113,6 +114,8 @@ class Builder extends BaseBuilder
*/
public $hint;

private ReadPreference $readPreference;

/**
* Custom options to add to the query.
*
Expand Down Expand Up @@ -211,7 +214,7 @@ public function project($columns)
/**
* The maximum amount of seconds to allow the query to run.
*
* @param int $seconds
* @param int|float $seconds
*
* @return $this
*/
Expand Down Expand Up @@ -454,7 +457,7 @@ public function toMql(): array

// Apply order, offset, limit and projection
if ($this->timeout) {
$options['maxTimeMS'] = $this->timeout * 1000;
$options['maxTimeMS'] = (int) ($this->timeout * 1000);
}

if ($this->orders) {
Expand Down Expand Up @@ -1534,6 +1537,24 @@ public function options(array $options)
return $this;
}

/**
* Set the read preference for the query
*
* @see https://www.php.net/manual/en/class.mongodb-driver-readpreference.php
*
* @param string $mode
* @param array $tagSets
* @param array $options
*
* @return $this
*/
public function readPreference(string $mode, ?array $tagSets = null, ?array $options = null): static
{
$this->readPreference = new ReadPreference($mode, $tagSets, $options);

return $this;
}

/**
* Performs a full-text search of the field or fields in an Atlas collection.
* NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments.
Expand Down Expand Up @@ -1642,6 +1663,10 @@ private function inheritConnectionOptions(array $options = []): array
}
}

if (! isset($options['readPreference']) && isset($this->readPreference)) {
$options['readPreference'] = $this->readPreference;
}

return $options;
}

Expand Down
26 changes: 26 additions & 0 deletions tests/Query/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Mockery as m;
use MongoDB\BSON\Regex;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Driver\ReadPreference;
use MongoDB\Laravel\Connection;
use MongoDB\Laravel\Query\Builder;
use MongoDB\Laravel\Query\Grammar;
Expand Down Expand Up @@ -1416,6 +1417,31 @@ function (Builder $elemMatchQuery): void {
['find' => [['embedded._id' => 1], []]],
fn (Builder $builder) => $builder->where('embedded->id', 1),
];

yield 'options' => [
['find' => [[], ['comment' => 'hello']]],
fn (Builder $builder) => $builder->options(['comment' => 'hello']),
];

yield 'readPreference' => [
['find' => [[], ['readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED)]]],
fn (Builder $builder) => $builder->readPreference(ReadPreference::SECONDARY_PREFERRED),
];

yield 'readPreference advanced' => [
['find' => [[], ['readPreference' => new ReadPreference(ReadPreference::NEAREST, [['dc' => 'ny']], ['maxStalenessSeconds' => 120])]]],
fn (Builder $builder) => $builder->readPreference(ReadPreference::NEAREST, [['dc' => 'ny']], ['maxStalenessSeconds' => 120]),
];

yield 'hint' => [
['find' => [[], ['hint' => ['foo' => 1]]]],
fn (Builder $builder) => $builder->hint(['foo' => 1]),
];

yield 'timeout' => [
['find' => [[], ['maxTimeMS' => 2345]]],
fn (Builder $builder) => $builder->timeout(2.3456),
];
}

#[DataProvider('provideExceptions')]
Expand Down

0 comments on commit 697c36f

Please sign in to comment.