-
Notifications
You must be signed in to change notification settings - Fork 1.4k
PHPORM-209 Add query builder helper to set read preference #3244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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; | ||
|
||
|
@@ -113,6 +114,8 @@ class Builder extends BaseBuilder | |
*/ | ||
public $hint; | ||
|
||
private ReadPreference $readPreference; | ||
|
||
/** | ||
* Custom options to add to the query. | ||
* | ||
|
@@ -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 | ||
*/ | ||
|
@@ -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) { | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just want to confirm that you don't need the ability to clear a ReadPreference previously assigned to the builder. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most of the operations using the query builder cannot be unset. |
||
{ | ||
$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. | ||
|
@@ -1642,6 +1663,10 @@ private function inheritConnectionOptions(array $options = []): array | |
} | ||
} | ||
|
||
if (! isset($options['readPreference']) && isset($this->readPreference)) { | ||
$options['readPreference'] = $this->readPreference; | ||
} | ||
|
||
return $options; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted that this tests integer truncation. |
||
]; | ||
} | ||
|
||
#[DataProvider('provideExceptions')] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get why other properties are public. Using private by default to not add the new property to the API for no reason.