You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All a comparison operations in the filters consist of the left operand, operator and the right operand.
<left_operand> <operator> <right_operand>
Now the left operand can be only a entity field, and the right operand only a value. This is a simple and effective mechanic to solve the standard tasks. However, it has several restrictions:
I offer to introduce the concept of operand. All specifications take operands as arguments. Transformation operand in DQL delegated to operand. This is simplify the specifications and will open a lot of opportunities.
By default, the first argument is packed into the operand of the field, and the second into the operand of the value. This will partially maintain backward compatibility and make the usage of specifications more compact.
if (!($fieldinstanceof Operand)) {
$field = newField($field);
}
if (!($valueinstanceof Operand)) {
$value = newValue($value);
}
Some operands can be put into other operands. For example operand functions can be put into another function.
trim(lower(e.email)) = :email
Operands arithmetic operations also can be put into each other.
I don't think that we need to create the operand classes for each the database functions on each platforms. I think we may just check that the specified user function is supported by the current platform. See getCustomStringFunction, getCustomNumericFunction and getCustomDatetimeFunction methods in Doctrine Configuration class. As default, we can add a DQL Functions.
Usage
// DQL: e.day > :day
Spec::gt('day', $day);
// or
Spec::gt(Spec::field('day'), $day);
// or
Spec::gt(Spec::field('day', $dqlAlias), $day);
// DQL: e.day > :day
Spec::gt('day', $day);
// or
Spec::gt('day', Spec::value($day));
// or
Spec::gt('day', Spec::value($day, Type::DATE));
Use functions:
// DQL: size(e.products) > 2
Spec::gt(Spec::size('products'), 2);
// or
Spec::gt(Spec::fun('size', 'products'), 2);
// or
Spec::gt(Spec::fun('size', Spec::field('products')), 2);
// DQL: SELECT e, u FROM ...
Spec::addSelect(Spec::selectEntity($dqlAlias))
Use aliases for selection fields:
// DQL: SELECT e.name author FROM ...
Spec::select(Spec::selectAs(Spec::field('name'), 'author'))
Add single hidden field in the selected set:
// DQL: SELECT e, u.name HIDDEN author FROM ...
Spec::addSelect(Spec::selectHiddenAs(Spec::field('email', $dqlAlias), 'author')))
Use expression in selection for add product discount to the result:
// DQL: SELECT (e.price_old is not null and e.price_current < e.price_old) discount FROM ...
Spec::select(Spec::selectAs(
Spec::andX(
Spec::isNotNull('price_old'),
Spec::lt(Spec::field('price_current'), Spec::field('price_old'))
),
'discount'
))
Use aliases in conditions to search a cheap products:
// DQL: SELECT e.price_current price FROM ... WHERE price < :low_cost_limit
Spec::andX(
Spec::select(Spec::selectAs('price_current', 'price')),
Spec::lt(Spec::alias('price'), $low_cost_limit)
)
Use hidden field for order users by score:
// DQL: SELECT e, e.posts_count + e.likes_count HIDDEN score FROM User e ORDER BY score
Spec::andX(
Spec::addSelect(
Spec::selectHiddenAs(
Spec::add(Spec::field('posts_count'), Spec::field('likes_count')),
'score'
)
),
Spec::orderBy(
Spec::alias('score')
)
)
The text was updated successfully, but these errors were encountered:
When I began work on #164, I looked into abstracting the operand so that field or value could be either left or right hand side of the comparison.
This goes so much further and is a really powerful abstraction that opens up an order of magnitude more possibilities with the library.
It also addresses some use cases I've already come against already such as using hidden fields. Indeed today it would be very helpful for me to be able to select a single field, in the form of
// DQL: SELECT e.email FROM ...
Spec::select('email')
All a comparison operations in the filters consist of the left operand, operator and the right operand.
Now the left operand can be only a entity field, and the right operand only a value. This is a simple and effective mechanic to solve the standard tasks. However, it has several restrictions:
I offer to introduce the concept of operand. All specifications take operands as arguments. Transformation operand in DQL delegated to operand. This is simplify the specifications and will open a lot of opportunities.
By default, the first argument is packed into the operand of the field, and the second into the operand of the value. This will partially maintain backward compatibility and make the usage of specifications more compact.
Some operands can be put into other operands. For example operand functions can be put into another function.
Operands arithmetic operations also can be put into each other.
((e.price_old - e.price_current) / (e.price_current / 100)) > :discount
I don't think that we need to create the operand classes for each the database functions on each platforms. I think we may just check that the specified user function is supported by the current platform. See
getCustomStringFunction
,getCustomNumericFunction
andgetCustomDatetimeFunction
methods in Doctrine Configuration class. As default, we can add a DQL Functions.Usage
Use functions:
Nested functions:
Use field as left and right operand for find products with a discount:
Very complex specification for find products with a discount of greater than N percent:
Select single field:
Add single field in the selected set:
Add one more custom fields in the selected set:
Add single entry in the selected set:
Use aliases for selection fields:
Add single hidden field in the selected set:
Use expression in selection for add product discount to the result:
Use aliases in conditions to search a cheap products:
Use hidden field for order users by score:
The text was updated successfully, but these errors were encountered: