Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions guides/security/aspects.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ Be aware that injections are still possible even via CQL when the query structur
<div class="impl java">

```java
String entity = <from user input>;
String column = <from user input>;
String entity = ...; // from user input;
String column = ...; // from user input;
validate(entity, column); // validate entity and column, e.g. compare with positive list
Select.from(entity).columns(b -> b.get(column));
```
Expand Down
2 changes: 1 addition & 1 deletion guides/using-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@ For Java, you set the authentication type to `TOKEN_FORWARDING` for the destinat
You can implement it in your code:

```java
urlFromConfig = <read from config>
urlFromConfig = ...; // read from config
DefaultHttpDestination mockDestination = DefaultHttpDestination
.builder(urlFromConfig)
.name("order-service")
Expand Down
8 changes: 4 additions & 4 deletions java/cds-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ book.putPath("author.name", "Bram Stoker");
Using the generated [accessor interfaces](#generated-accessor-interfaces):
```java
Authors author = Authors.create();
author.setId(23)
author.setId(23);
author.setName("Bram Stoker");
Books book = Books.create();
book.setId(97);
Expand Down Expand Up @@ -342,7 +342,7 @@ In this example an order with a header in status 'open' is created via a deep in

```java
OrderHeaders header = OrderHeaders.create();
header.setId(11)
header.setId(11);
header.setStatus("open");

Orders order = Orders.create();
Expand Down Expand Up @@ -691,7 +691,7 @@ Filters can be defined as lambda expressions on `path`, `element`, and `type`, f

```java
(path, element, type) -> element.isKey()
&& type.isSimpleType(CdsBaseType.STRING)
&& type.isSimpleType(CdsBaseType.STRING);
```
which matches key elements of type String.

Expand Down Expand Up @@ -1221,7 +1221,7 @@ public class CoverImagePreProcessor extends FilterInputStream {

// ... your custom processing code on nextByte

return nextByte
return nextByte;
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion java/cqn-services/application-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public class CatalogServiceHandler implements EventHandler {
public void reviewAction(ReviewEventContext context) {
CqnSelect selectBook = context.getCqn();
Integer stars = context.getStars();
Reviews review = [...] // create the review
Reviews review = ...; // create the review
context.setResult(review);
}

Expand Down
6 changes: 3 additions & 3 deletions java/messaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void receiveMyTopic(TopicMessageEventContext context) {
// get ID and payload of message
String msgId = context.getMessageId();
String payload = context.getData();
...
}
```

Expand Down Expand Up @@ -154,7 +154,7 @@ public class ReviewServiceHandler implements EventHandler {
reviews.forEach(review -> {

// Calculate the new average rating
BigDecimal avg = [...]
BigDecimal avg = ...;

// Set event payload
Reviewed event = Reviewed.create();
Expand Down Expand Up @@ -595,7 +595,7 @@ cds:
public void receiveMyCustomQueueAllMessages(TopicMessageEventContext context) {
// access the message as usual
String payload = context.getData();
...
}
```

Expand Down
10 changes: 6 additions & 4 deletions java/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Modifier modifier = new Modifier() {
segments.add(0, CQL.refSegment(segments.get(0).id(), filter));
return CQL.get(segments).as(alias);
}
}
};
CqnStatement copy = CQL.copy(statement, modifier);
```

Expand Down Expand Up @@ -841,11 +841,13 @@ To access an Application Service in custom handler and to execute queries, perfo
Example of query execution in *Classic Java Runtime*:

```java
CDSDataSourceHandler cdsHandler = DataSourceHandlerFactory.getInstance().getCDSHandler(getConnection(), queryRequest.getEntityMetadata().getNamespace());
CDSDataSourceHandler cdsHandler = DataSourceHandlerFactory
.getInstance()
.getCDSHandler(getConnection(), queryRequest.getEntityMetadata().getNamespace());

CDSQuery cdsQuery = new CDSSelectQueryBuilder("CatalogService.Books")
.selectColumns("id", "title")
.where(new ConditionBuilder().columnName("title").IN("Spring", Java"))
.where(new ConditionBuilder().columnName("title").IN("Spring", "Java"))
.orderBy("title", true)
.build();

Expand Down Expand Up @@ -899,7 +901,7 @@ CDSDataSourceHandler cdsHandler = ...;

CDSQuery cdsQuery = new CDSSelectQueryBuilder("CatalogService.Books")
.selectColumns("id", "title")
.where(new ConditionBuilder().columnName("title").IN("Spring", Java"))
.where(new ConditionBuilder().columnName("title").IN("Spring", "Java"))
.orderBy("title", true)
.build();

Expand Down
2 changes: 1 addition & 1 deletion java/reflection-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ CdsModel model;
On a lower level, the `CdsModel` can be obtained from the `CdsDataStoreConnector`, or using the `read` method from a [CSN](../cds/csn) String or [InputStream](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html):

```java
InputStream csnJson = ...
InputStream csnJson = ...;
CdsModel model = CdsModel.read(csnJson);
```

Expand Down
48 changes: 25 additions & 23 deletions java/working-with-cql/query-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ Select.from(AUTHORS)
.columns(a -> a.name().as("author"),
a -> a.books().expand(
b -> b.title().as("book"),
b -> b.year());
b -> b.year()));
```

<span id="indeepread" />
Expand Down Expand Up @@ -389,7 +389,7 @@ Select.from(AUTHORS)
.columns(a -> a.name(),
a -> a.books()
.filter(b -> b.year().eq(1897))
.expand(b -> b.title())
.expand(b -> b.title()))
.where(a -> name().in("Bram Stroker", "Edgar Allen Poe"));
```

Expand All @@ -415,7 +415,7 @@ Select.from(AUTHORS)
.columns(a -> a.name(),
a -> a.books().as("novels").expand(
b -> b.title(),
b -> b.publisher().expand(p -> p.name()));
b -> b.publisher().expand(p -> p.name())));
```

Which returns a deeply structured result:
Expand Down Expand Up @@ -497,7 +497,7 @@ Select.from(AUTHORS)
.columns(a -> a.name(),
a -> a.books().inline(
b -> b.title().as("book"),
b -> b.year());
b -> b.year()));
```

Both queries are equivalent and have the same result: a _flat_ structure:
Expand Down Expand Up @@ -670,7 +670,7 @@ The following example selects authors where count is higher than 2:

```java
Select.from("bookshop.Authors")
.columns(c -> c.get("name")), c -> func("count", c.get("name")).as("count")
.columns(c -> c.get("name"), c -> func("count", c.get("name")).as("count"))
.groupBy(c -> c.get("name"))
.having(c -> func("count", c.get("name")).gt(2));
```
Expand Down Expand Up @@ -1306,7 +1306,7 @@ import static com.sap.cds.ql.CQL.val;

Select.from(EMPLOYEE)
.columns(e -> e.name())
.where(e -> val(50).gt(e.age());
.where(e -> val(50).gt(e.age()));
```

Alternatively, the factory methods for comparison predicates directly accept Java values. The query could also be written as:
Expand Down Expand Up @@ -1656,7 +1656,7 @@ BETWEEN
The [ETag predicate](query-execution#etag-predicate) specifies expected ETag values for [conflict detection](query-execution#optimistic) in an [update](#update) or [delete](#delete) statement:

```java
Instant expectedLastModification = ... ;
Instant expectedLastModification = ...;
Update.entity(ORDER)
.entry(newData)
.where(o -> o.id().eq(85).and(o.eTag(expectedLastModification)));
Expand All @@ -1667,7 +1667,7 @@ You can also use the `eTag` methods of the `CQL` interface to construct an ETag
```java
import static com.sap.cds.ql.CQL.*;

Instant expectedLastModification = ... ;
Instant expectedLastModification = ...;
Update.entity(ORDER)
.entry(newData)
.where(and(get("id").eq(85), eTag(expectedLastModification)));
Expand Down Expand Up @@ -1826,7 +1826,7 @@ As a general rule, consider regular expressions as a last resort. They are power
In the following example, the title of the book must start with the letter `C` and end with the letter `e` and contains any number of letters in between:

```java
Select.from("bookshop.Books").where(t -> t.get("title").matchesPattern("^C\w*e$"));
Select.from("bookshop.Books").where(t -> t.get("title").matchesPattern("^C\\w*e$"));
```

The behavior of the regular expression can be customized with the options that can be passed as a second argument of the predicate. The set of the supported options and their semantics depends on the underlying database.
Expand Down Expand Up @@ -1889,9 +1889,9 @@ import static spaceflight.Astronautics_.ASTRONAUTS;
// fluent style
Select.from(AUTHORS)
.where(author -> author.exists($outer ->
Select.from(ASTRONAUTS).where(astro -> astro.name().eq($outer.name())))
Select.from(ASTRONAUTS).where(astro -> astro.name().eq($outer.name()))
)
)
);
```

This query selects all authors with the name of an astronaut.
Expand All @@ -1918,8 +1918,10 @@ Select.from("Authors").where(CQL.exists(subquery));
[CQL](../../cds/cql) queries can also be constructed from a [CQN](../../cds/cqn) string<sup>*</sup>:

```java
String cqnQuery = "{'SELECT': {'from': {'ref': ['my.bookshop.Books']},
'where': [{'ref': ['title']}, '=', {'val': 'Capire'}]}}";
String cqnQuery = """
{'SELECT': {'from': {'ref': ['my.bookshop.Books']},
'where': [{'ref': ['title']}, '=', {'val': 'Capire'}]}}
""";
CqnSelect query = Select.cqn(cqnQuery);
```

Expand All @@ -1944,16 +1946,16 @@ As opposed to fluent API it's possible to build the queries in a tree-style. Con

```java
// CQL: SELECT from Books where year >= 2000 and year <= 2010

AND
|
+---------+---------+
| |
=> <=
| |
+----+----+ +----+----+
| | | |
year 2000 year 2010
//
// AND
// |
// +---------+---------+
// | |
// => <=
// | |
// +----+----+ +----+----+
// | | | |
// year 2000 year 2010

import static com.sap.cds.ql.CQL.*;
import com.sap.cds.sql.cqn.CqnComparisonPredicate;
Expand Down
4 changes: 2 additions & 2 deletions java/working-with-cql/query-execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ An ETag can also be used programmatically in custom code. Use the `CqnEtagPredic

```java
PersistenceService db = ...
Instant expectedLastModification = ...
Instant expectedLastModification = ...;
CqnUpdate update = Update.entity(ORDER).entry(newData)
.where(o -> o.id().eq(85).and(
o.eTag(expectedLastModification)));
Expand Down Expand Up @@ -362,7 +362,7 @@ orders.forEach(o -> o.setStatus("cancelled"));

Result rs = db.execute(Update.entity(ORDER).entries(orders));

for(int i = 0; i orders.size(); i++) if (rs.rowCount(i) == 0) {
for(int i = 0; i < orders.size(); i++) if (rs.rowCount(i) == 0) {
// order does not exist or was modified concurrently
}
```
Expand Down
7 changes: 4 additions & 3 deletions java/working-with-cql/query-introspection.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Select.from("bookshop.Book").where(b -> b.get("ID").eq(42));

```java
Select.from("bookshop.Book")
.where(b -> b.get("ID").eq(42).and(b.get("title").is("Capire"));
.where(b -> b.get("ID").eq(42).and(b.get("title").is("Capire")));
```

This rule also applies to all segments of all references of the query, be it simple query or the one with path expression:
Expand Down Expand Up @@ -256,7 +256,7 @@ Predicate filter = CQL.and(titles, stock);

The `filter` consists of three predicates, substituting the following tree:

```java
```
AND
┌───────────────────┴───────────────────┐
IN GT
Expand All @@ -266,7 +266,7 @@ The `filter` consists of three predicates, substituting the following tree:

which corresponds to the following CQN token tree (numbers in brackets show the visit order):

```java
```
CqnConnectivePredicate (8)
┌───────────────────┴───────────────────┐
CqnInPredicate (4) CqnComparisonPredicate (7)
Expand All @@ -293,6 +293,7 @@ class CheckDataVisitor implements CqnVisitor {
return (Boolean) stack.pop();
}
...
}
```

On the leaf-level, the stack is used to store the concrete values from both data payload and filter expression:
Expand Down