-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
New PSR for data querying #1284
Open
alexandre-daubois
wants to merge
1
commit into
php-fig:master
Choose a base branch
from
alexandre-daubois:feat/psr/query
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
Common Interface for data querying | ||
================================== | ||
|
||
This document describes common interfaces to query data. These data can be from different sources, from in-memory data to databases, as well as filesystem files. | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be | ||
interpreted as described in [RFC 2119][]. | ||
|
||
The final implementations MAY decorate the objects with more | ||
functionality than the one proposed but they MUST implement the indicated | ||
interfaces/functionality first. | ||
|
||
[RFC 2119]: http://tools.ietf.org/html/rfc2119 | ||
|
||
## 1. Specification | ||
|
||
### 1.1 Goal | ||
|
||
There are numerous ways of querying data from so many sources. Each system has its very own way of doing it. For instance, Doctrine ORM and Symfony Finder are both querying data with query builders (or alike), but there is no standardized interface to implement such data querying. | ||
|
||
The goal of this PSR it to define common interfaces to query data, no matter where they come from (arrays, iterators, etc.) or their format. | ||
|
||
### 1.2 Definitions | ||
|
||
* **Query** - The object that will be used to query data. It receives a source as an `iterable`, which allows processing of arrays as well as other type of collections like generators. | ||
|
||
* **Modifier** - A modifier is an action applied to the source, which will be executed before each operation. There can be multiple modifiers on a Query, for instance a `where` clause, an `order by`, a `limit` or even an `offset`. Operations are applied _after_ modifiers. | ||
|
||
* **Operation** - An operation is a one-time action applied to a processed source, after all modifiers has been applied. An operation can return any type of data: generators, scalars, etc. | ||
|
||
* **Context** - What holds additional information to be passed to the query, modifiers and operations in the case they need it. | ||
|
||
## 2. Interfaces | ||
|
||
### 2.1 QueryInterface | ||
|
||
Has the ability to query an iterable source. | ||
|
||
```php | ||
namespace Psr\Query; | ||
|
||
use Psr\Query\QueryContextInterface; | ||
use Psr\Query\QueryModifierInterface; | ||
use Psr\Query\QueryOperationInterface; | ||
|
||
/** | ||
* Defines an object which will execute modifiers and operations to query data. | ||
* A QueryInterface could receive any iterable depending on the implementation. This could go from the | ||
* basic array of data to generators. | ||
*/ | ||
interface QueryInterface | ||
{ | ||
/** | ||
* Creates a new object to query data. | ||
* | ||
* @param iterable $source | ||
* The source to apply manipulations on. | ||
* | ||
* @param QueryContextInterface|null $context | ||
* The optional context that forward needed information to the Query for its execution. | ||
* | ||
* @return static | ||
*/ | ||
public static function from(iterable $source, QueryContextInterface $context = null): static; | ||
|
||
/** | ||
* Get the context of the current Query, possibly modified by the latter. | ||
* | ||
* @return QueryContextInterface | ||
*/ | ||
public function getContext(): QueryContextInterface; | ||
|
||
/** | ||
* Gets the source of the Query. | ||
* | ||
* @return iterable | ||
*/ | ||
public function getSource(): iterable; | ||
|
||
/** | ||
* Applies a modifier to the Query. | ||
* | ||
* @param QueryModifierInterface $modifier | ||
* The actual modifier to apply. | ||
* | ||
* @return static | ||
*/ | ||
public function applyModifier(QueryModifierInterface $modifier): static; | ||
|
||
/** | ||
* Applies an operation to the Query. | ||
* | ||
* @param QueryOperationInterface $operation | ||
* The actual operation to apply. | ||
* | ||
* @return mixed | ||
*/ | ||
public function applyOperation(QueryOperationInterface $operation): mixed; | ||
} | ||
``` | ||
|
||
### 2.2 QueryContextInterface | ||
|
||
Has the ability to hold and transmit information to the Query, which would be needed for modifiers and operations to be applied. | ||
|
||
```php | ||
namespace Psr\Query; | ||
|
||
/** | ||
* Defines the context of a Query. This could be used to pass additional data to the query, such as | ||
* already used alias in the current Query context. | ||
*/ | ||
interface QueryContextInterface | ||
{ | ||
} | ||
``` | ||
|
||
### 2.3 QueryModifierInterface | ||
|
||
Applies some modification on Query's source, before applying a final operation on the processed source. | ||
|
||
```php | ||
namespace Psr\Query; | ||
|
||
use Psr\Query\QueryInterface; | ||
|
||
/** | ||
* Defines a Query modifier. A modifier is applied before any operation. This could be a `where` clause, as well | ||
* as an ordering, a shuffling, limiting the max number of results, etc. | ||
*/ | ||
interface QueryModifierInterface | ||
{ | ||
/** | ||
* Applies the modifier to the given source, and returns the result of this modifier. | ||
* | ||
* @param QueryInterface $query | ||
* The source to apply the modifier on. | ||
* | ||
* Optional context if needed by the modifier. | ||
* | ||
* @return iterable | ||
* The modified source. | ||
*/ | ||
public function apply(QueryInterface $query): iterable; | ||
} | ||
``` | ||
|
||
### 2.4 QueryOperationInterface | ||
|
||
Applies a final operation to source after modifiers has been applied, and returns the result. The result can be of any type, according to what the operation actually does. | ||
|
||
```php | ||
namespace Psr\Query; | ||
|
||
use Psr\Query\QueryInterface; | ||
|
||
/** | ||
* Defines a final operation done to the source, after modifiers has been applied. An operation can be | ||
* a simple concatenation, selecting data, get an average/min/max value, etc. | ||
*/ | ||
interface QueryOperationInterface | ||
{ | ||
/** | ||
* @param QueryInterface $query | ||
* The source to apply the operation on. | ||
* | ||
* @return mixed | ||
* The result of the operation. This can be any type of data, depending on what the operation actually does. | ||
*/ | ||
public function apply(QueryInterface $query): mixed; | ||
} | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
"context objects" are a code smell.
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 can understand this. Maybe
getContext
,context
arguments andQueryContextInterface
could simply be removed!