Bump byte-buddy to 1.12.9
[mdsal.git] / docs / query-binding-language-developer-guide.rst
1 .. _mdsal-binding-dev-guide:
2
3 MD-SAL Binding Query Language Developer Guide
4 =============================================
5
6 .. note::
7
8         Reading this section is likely useful as it contains an overview
9         of MD-SAL Binding query language in OpenDaylight and a how-to use it for
10         retrieving data from data storage.
11
12 Retrieving data from storage
13 ----------------------------
14
15 MD-SAL has two ways (operations) of retrieving data from storage: read-like and query-like operations.
16
17 Read-like operation
18 ~~~~~~~~~~~~~~~~~~~
19
20 The method **read** of ReadTransaction interface.
21
22 ::
23
24         <T extends DataObject> FluentFuture<Optional<T>> read(LogicalDatastoreType store, InstanceIdentifier<T> path);
25
26 The method reads data from the provided logical data store located at the provided path.
27 If the target is a subtree, then the whole subtree is read (and will be accessible from the returned DataObject).
28 So we are getting DataObject which we need to process in code for getting relevant data:
29
30 ::
31
32     FluentFuture<Optional<Foo>> future;
33     try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) {
34         future = rtx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Foo.class));
35     }
36     Foo haystack = future.get().orElseThrow();
37     Object result = null;
38     for (System system : haystack.nonnullSystem().values()) {
39         if (needle.equals(system.getAlias())) {
40             result = system;
41             break;
42         }
43     }
44
45 .. note::
46
47         The structure of the Foo container is `here`_.
48
49 .. _here: https://github.com/opendaylight/mdsal/blob/master/binding/mdsal-binding-test-model/src/main/yang/mdsal-query.yang
50
51 Query-like operation
52 ~~~~~~~~~~~~~~~~~~~~
53
54 The method **execute** of QueryReadTransaction interface.
55
56 ::
57
58         <T extends DataObject> FluentFuture<QueryResult<T>> execute(LogicalDatastoreType store, QueryExpression<T> query);
59
60 The method executes a query on the provided logical data store for getting relevant data.
61 So we are getting result which we need for future business logic processing.
62 Before running the method execute we need to prepare a query with the match predicates.
63 For example, we want to find in Foo container the System with alias **target-needle**:
64
65 ::
66
67     String needle = "target-needle";
68     QueryExpression<System> query = factory.querySubtree(InstanceIdentifier.create(Foo.class))
69         .extractChild(System.class)
70             .matching()
71                 .leaf(System::getAlias).valueEquals(needle)
72             .build();
73
74 The method **querySubtree** creates a new **DescendantQueryBuilder** for a specified root path. It's intermediate query builder stage,
75 which allows the specification of the query result type to be built up via **extractChild(Class)** and
76 **extractChild(Class, Class)** methods. They used to specify which object type to select from the root path.
77 Once completed, use either **build()** to create a simple query, or **matching()** to transition to specify predicates.
78 There is a bunch of overloaded methods **leaf** which based on the type of arguments returns specific match builders:
79
80 - ValueMatchBuilder methods:
81
82 | **ValueMatch<T> nonNull();**
83 | **ValueMatch<T> isNull();**
84 | **ValueMatch<T> valueEquals(V value);**
85
86 - ComparableMatchBuilder extends ValueMatchBuilder and adds methods:
87
88 | **ValueMatch<T> lessThan(V value);**
89 | **ValueMatch<T> lessThanOrEqual(V value);**
90 | **ValueMatch<T> greaterThan(V value);**
91 | **ValueMatch<T> greaterThanOrEqual(V value);**
92
93 - StringMatchBuilder extends ValueMatchBuilder and adds methods:
94
95 | **ValueMatch<T> startsWith(String str);**
96 | **ValueMatch<T> endsWith(String str);**
97 | **ValueMatch<T> contains(String str);**
98 | **ValueMatch<T> matchesPattern(Pattern pattern);**
99
100 After creation of query, we can use it in the method execute of QueryReadTransaction interface:
101
102 ::
103
104     FluentFuture<QueryResult<System>> future;
105     try (ReadTransaction rtx = getDataBroker().newReadOnlyTransaction()) {
106         future = ((QueryReadTransaction) rtx).execute(LogicalDatastoreType.CONFIGURATION, query);
107     }
108     QueryResult<System> result = future.get();