-
Notifications
You must be signed in to change notification settings - Fork 7
EQL Guide
When a component-typed property is used as an operand (e.g., comparison condition, yield operand), it has to be resolved against the source of the query. Since a property is a single-valued (scalar) operand, and a component type may have multiple components, a component-typed property implicitly represents one of its components.
As of TG version 2.0.0, the following implicit representations are used:
-
Money
- sub-propertyamount
. -
RichText
- sub-propertycoreText
.
For example, the following yields can be used interchangeably:
yield().prop("price") // implicitly resolved to "price.amount"
yield().prop("price.amount")
This section describes how to use component-typed properties in yields, both as yield operands and aliases.
The treatment of component-typed properties as yield operands is the same as in other contexts. Refer to the section about resolution of component-typed properties.
Support for component-typed properties in yield aliases is limited. Such properties can be used standalone in yield aliases only in a source query. In all other kinds of queries, component sub-properties must be yielded explicitly.
For the sake of demonstration, assume the following entity:
class Invoice extends AbstractEntity {
@IsProperty
@MapTo
RichText comment;
@IsProperty
@MapTo
Money fee;
}
The following yields use standalone component-typed properties as aliases, and are valid only in a source query:
yield().X.as("fee")
yield().X.as("comment")
An outer query that uses a source query with such yields can refer to them via prop
as-is. I.e., property resolution works as expected in such cases.
sourceQ = select().
yield().X.as("fee"). // (1)
modelAsEntity(Note.class);
q = select(sourceQ).
yield().beginExpr().prop("fee").mult().val(2).endExpr().as("fee.amount"). // (2)
modelAsEntity(Note.class);
In the query above, the source query doesn't need to include .amount
in the alias (1), and its enclosing query can refer to fee
(recall that prop("fee")
will expand to prop("fee.amount")
).
However, the top-level query must specify the full component sub-property path (2) in the yield alias.
This limited form of support is useful for working with synthetic entities. Synthetic entity models are always interpreted as source queries, enabling the use of alias shortcuts described in this section.
A source query is a query that is used as a source of another query.
Example:
select(
// source query 1
select(InventoryItem.class).yield().prop("price").as("cost").modelAsEntity(ReTransaction.class),
// source query 2
select(ReturnReceipt.class).yield().prop("refund").as("cost").modelAsEntity(ReTransaction.class)
)
.where().prop("cost").ge().val(100)
.modelAsEntity(ReTransaction.class)
If two or more source queries are used, they form a union.
A query that contains source queries is subject to the following constraints:
-
If two or more source queries are used, they must have the same number of yields and use the same set of yield aliases.
The following examples demonstrate invalid queries:
-
Different numbers of yields.
select( // 2 yields select(InventoryItem.class) .yield().prop("price").as("cost") .yield().prop("id").as("id") .modelAsEntity(ReTransaction.class), // 1 yield select(ReturnReceipt.class) .yield().prop("refund").as("cost") .modelAsEntity(ReTransaction.class) )
-
Different sets of yield aliases.
select( // { "cost", "id" } select(InventoryItem.class) .yield().prop("price").as("cost") .yield().prop("id").as("id") .modelAsEntity(ReTransaction.class), // { "expense", "id" } select(ReturnReceipt.class) .yield().prop("price").as("expense") .yield().prop("id").as("id") .modelAsEntity(ReTransaction.class) )
-
Per aspera ad astra
- Web UI Design and Web API
- Safe Communication and User Authentication
- Gitworkflow
- JavaScript: Testing with Maven
- Java Application Profiling
-
TG Development Guidelines
- TLS and HAProxy for development
- TG Development Checklist
- Entities and their validation
- Entity Properties
- Entity Type Enhancement
- EQL
- Tooltip How To
- All about Matchers
- All about Fetch Models
- Streaming data
- Synthetic entities
- Activatable entities
- Jasper Reports
- Opening Compound Master from another Compound Master
- Window management test plan
- Multi Time Zone Environment
- GraphQL Web API
- Guice
- Maven
- Full Text Search
- Deployment recipes
- Application Configuration
- JRebel Installation and Integration
- Compile-time mechanisms
- Work in progress