The Coolest Language-Integrated Query Feature in Ballerina, “Query Expression”!!
Ballerina is an open-source programming language developed by WSO2 which allows programmers to do DevOps and Agile-Oriented development quite easily. It is unique from many other existing programming languages because of its,
- support in networking, existent in the language syntax itself
- visual representation of the program logic as sequence diagrams
- ease in moving from code to cloud, and many more.
To find out more about Ballerina, check out the Ballerina website here.
Among many other new features, Query Expression is one of the coolest features 😉 introduced with Ballerina 1.2.0. It provides a way to perform query functionality using SQL-like syntax.
A query expression is similar to a list comprehension and consists of a sequence of clauses. from
, let
, where
, select
, and limit
are some of the available query clauses. If the execution of a query clause is completed early with an error value, the result of the query is this error value. Otherwise, the result of the query expression is either a list
, stream
, table
, string
or an xml
constructed from the sequence of values emitted by the last clause.
The following is a use-case of a query expression. (I’m trying out these examples with the latest Ballerina Swan Lake preview version, swan-lake-preview2)
The from
clause works similar to a foreach
statement. It iterates the customerList
. The let
clause binds variables. The where
clause applies a boolean condition on each element in the customerList
and filters the ones for which the specified condition is true
. If the condition evaluates to false
, the subsequent clauses are omitted for that iteration. The select
clause emits the output values. It is evaluated for each iteration. The number of output items is limited by the limit
clause. The result of this query expression is a list
of Customers
.
A boolean value true
is assigned to variableloyalty
using the let
clause. The where
clause ensures that only customers
with noOfItems > 15
are filtered from the customerList
. The customerId, name, noOfItems
values of each customer
in the customerList
is assigned to customerId, name, noOfItems
fields and value of loyalty
is assigned to isLoyalMember
field of each Customer
emitted from the select
clause. In the above example, customers with customerId
2
, 3
, and5
satisfy the given condition. But the limit
clause will limit the number of items to two. Therefore the output of the above query expression
will be the following.
customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true
Stream from the query expression
To construct a bounded stream from the query expression
you simply need to add the stream
keyword with the from
clause.
The output stream
from the above query expression
will contain the same values as the list
output.
customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true
Table from the query expression
Adding the table
keyword with a key specifier as a prefix for the from
clause constructs a table from query expression
.
A CustomerTable
table
type with Customer
members uniquely identified by their customerId
and name
is created to capture the output from the query expression
. The outputTable
will contain the following members.
customerId=2 name=Tobi noOfItems=20 isLoyalMember=true
customerId=3 name=Frank noOfItems=30 isLoyalMember=true
With keyed tables, key conflicts can occur when select
emits a row that has the same key as a row that it emitted earlier. Then a key conflict error
will be output from the query expression
. In order to customize this key conflict error, you can include an on conflict
clause specifying the error that you want to have for a key conflict.
It is required that the keyConflictErr
expression belongs to error
type. In the above example Customer
c3
is repeated in the customerList
. Therefore a key conflict will occur when select
tries to emit a customer
with the same keys twice, since the keyed table constructed from the query expression
can not consist of two members with the same (customerId, name)
.
Then the result of the query expression
;outputTable
will be the following when a key conflict is present.
error Key conflict in query
String from the query expression
When a string
is constructed from the query expression
, it concatenates the string
type values emitted from the select
clause to form the output string
.
The output from the above query expression
will be,
Tobi 20,Frank 30,
XML from the query expression
Similar to string
, the XML
type values emitted from the select
clause is concatenated to form the XML
output from query expression
.
The output from the above query expression
will be,
<name>Melina</name><name>Tobi</name>
That’s it! Hope you got an understanding about Query Expression
in Ballerina. 😄 There are a lot more cool stuff that can be done using query expression
. Let’s try them out in the upcoming articles. 😃
Adiós!!
References
https://ballerina.io/
https://ballerina.io/spec/lang/draft/v2020-06-18/