February 2022
Welcome to the release of CAP. Find the most noteworthy news and changes in the following sections.Capire Docs & Samples
Keyboard Shortcuts in Capire
We now provide an overview of the available keyboard shortcuts in capire. Just try it out and hit ? to see this list:
Revised Cookbook - Deploy & Operate
This cookbook is based on the deployment guide that was previously found in the Advanced section of capire. We revised it and promoted the guide to a cookbook.
Assuming you have developed your application, it's tested and running, and ready for deployment. Before you start to automate, you want to do the necessary preparation and deploy ad-hoc, to see if everything works as before. This guide helps you.
Data Browser Sample
We have added a simple generic data browser to the sample suite for Node.js, useful for troubleshooting purposes during application development:
You can browse entities from all connected services of the application. Data is either fetched directly from the database or through the application's CDS services, which then includes projections, validations and so on.
The sample code also demonstrates the following:
- How to write a generic CAP service (see the data-viewer package).
- How to include such a service and its UI in another application (the bookstore app).
Note that this code is meant for demonstration purposes and should not be used in production. Copy the code into your application as needed.
Key-User Extensions with SAPUI5 Flexibility
We added a first experimental support for simple field extensibility in CAP.
❗ Warning
This is only disclosed for testing purposes and for gathering feedback.
Current limitations:
- Only works locally using
cds watch
- Needs to be deployed to a file-based SQLite database
- Only available for the Node.js runtime
This is a first step to enable extensibility in CAP applications without depending on an MTX/HDI based deployment and an SAP HANA database.
Multiline String Literals
Multiline string literals enclosed in single or triple backticks provide a convenient way of writing long text snippets, for example in annotation values. In addition, they support escape sequences. The variant with triple backticks performs indentation stripping and allows tagging.
annotate Customer with @Cache.UpdateHandler:
{
XMLHttpRequest : `PUT /patients`,
XMLRequestBody : ```xml
<patient id="\${entity.PatientID}">
<name>\${entity.Name}</name>
<state>\u{1f197}</state>
<address>\${entity.Address}</address>
<dateOfBirth>\${entity.DOB}</dateOfBirth>
<patient>
```
}
Learn more about Multiline Literals.
Native Database Clauses beta
Activate this feature in .cdsrc.json:
"cdsc": {
"beta": { "sqlSnippets": true }
}
Using the annotations @sql.prepend
and @sql.append
, you can add arbitrary SQL snippets to the DDL statements that are generated by the compiler. This allows to use database features that are not natively supported by CDS.
Model:
@sql.append: ```sql
GROUP TYPE foo
GROUP SUBTYPE bar
```
entity E {
...,
@sql.append: 'FUZZY SEARCH INDEX ON'
text: String(100);
}
Result:
create table E (
...,
text nvarchar(100) FUZZY SEARCH INDEX ON
) GROUP TYPE foo
GROUP SUBTYPE bar
❗ Warning
The compiler doesn't check or process the provided SQL snippets in any way. You are responsible to ensure that the resulting statement is valid and doesn't negatively impact your database or your application. We don't provide support for problems caused by using this feature.
Learn more about Native Database Clauses.
Extend Array-Like Annotation Values - Insert
In addition to adding new entries at the beginning and at the end of an array-like annotation value, you can now insert them at arbitrary positions. Provide a comparator object to identify the entry after which to insert.
For displaying the day of week after the respective fields for BeginDate
and EndDate
:
@UI.LineItem : [
{ Value : TravelID },
{ Value : BeginDate },
{ Value : EndDate },
{ Value : TotalPrice },
{ Value : Description }
]
entity TravelService.Travel { /* elements */ }
use the new ... up to
syntax:
annotate TravelService.Travel with @UI.LineItem: [
... up to { Value : BeginDate },
{ Value : BeginWeekday }, // inserted after BeginDate
... up to { Value : EndDate },
{ Value : EndWeekday }, // inserted after EndDate
... // remaining array values
];
Node.js Runtime
Important Changes ❗️
- Draft entities can only be updated by the user that created the draft. From this release on, this rule includes bound actions and functions. See Restrictions and Draft Mode for more details.
- In OData, binary data (whether as payload or part of query options) is consistently passed into the service as Base64 encoded strings.
New Hook req.before('commit')
The new hook req.before('commit') allows you to perform some final actions, such as validity checks, bookkeeping, and so on, before the respective transaction is committed. Throwing an error vetoes the commit.
Example:
srv.before('CREATE', Order, function(req) {
req.before('commit', async function() {
const { creditscore } = await SELECT.one.from(Customers)
.where({ ID: req.data.customer_ID })
if (creditscore < 42) throw new Error("We shouldn't make this sale")
})
})
Media Data
The new OData annotation @Core.ContentDisposition.Type
is now supported, with attachment
as the default value.
Further, we added beta support for returning custom stream objects in custom handlers as described in Custom Streaming.
Java SDK
Synchronous In-Memory Messaging to Ease Testing
The new in-memory MessagingService
can be easily consumed in local testing scenarios or JUnit tests. To create such a messaging service, choose local-messaging
as kind:
cds:
messaging.services:
- name: "messaging"
kind: "local-messaging"
The MessagingService
provides the common messaging service API, but the event publishing is synchronous to the event listeners. This frees test code from having to wait on the asynchronous execution of the listeners.
Instance-Based Authorization with IN
Predicates
IN
predicates with user attributes are now supported in instance-based authorization conditions, for example, country in $user.countries
. Logically, it has the same effect as the =
-operator in predicates (for example: country = $user.countries
), but the $user
-attribute value (list) needs to be a right operand.
Exclude Sensitive Data from Logging
Potentially, sensitive values are now excluded from CQN statements in application logging by default. To enable logging of sensitive values again you can set cds.security.logPotentiallySensitive
to true
.
Analyze a CQN Expression Tree
Use a CqnVisitor for in-depth analysis of a CQN expression tree. Use cases:
- Transformation of CQN to some different query language
- In-memory evaluation of CQN
- Overcome limitations of the
CqnAnalyzer
ORDER BY ... NULLS FIRST | LAST
You may now specify if null
values are to appear first or last in a sorted result of a read query. The following query sorts the authors by year of death with the live authors appearing last:
Select.from(AUTHOR).orderyBy(a -> a.yearOfDeath().ascNullsLast());
Misc
The audit logging implementation now handles
@PersonalData.EntitySemantics: 'Other'
as defined in Audit Logging.The OData V2 adapter now handles
@Aggregation.default: #COUNT
.To support deferred foreign key constraints in SQLite during the CSV data import, all CSV files can be imported in an atomic change set. This behavior can be enabled by setting the new property
cds.dataSource.csvSingleChangeset
totrue
.You may now write through a projection with calculated fields. The calculated fields will be silently ignored.
Command Line Client for CDS Code Formatter beta
Up to now the CDS code formatter was only accessible in an IDE that uses the CDS language server, for example, VS Code with the SAP CDS Language Support extension.
The CDS code formatter now provides a command line interface. This is especially helpful to guarantee a consistent formatting, for example, as a pre-commit hook or within your CI/CD pipeline.
Learn how to use the code formatter CLI.
CDS Editor
Workspace Symbols Query Supports Filters for Artifact Kinds
Workspace Symbols can now be filtered by kinds, for example: entity:...
or service:...
. The kind can be shortened, for example, s:...
for services. A shortcut kind may match multiple kinds: e:...
matches entities, enums, and elements.
Performance and Memory Improvements
The CDS language server is now bundled and minified to further reduce startup time. The caching of indexes was optimized to reduce memory.
Improved Code Completion
Code completion for index.cds files now renders just the folder when selected.
Archived Changelogs 2021
When you're looking for our changelog, you'll notice that we "archived" already our changelog for the past year. You can still search, navigate and find it. But we rearranged the content to keep the most recent content at the top.