Couchbase Lite C++
Couchbase Lite C++ API
Loading...
Searching...
No Matches
Query.hh
Go to the documentation of this file.
1//
2// Query.hh
3//
4// Copyright (c) 2019 Couchbase, Inc All rights reserved.
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17//
18
19#pragma once
20#include "cbl++/Database.hh"
21#include "cbl/CBLQuery.h"
22#include <stdexcept>
23#include <string>
24#include <string_view>
25#include <vector>
26
27
29
30namespace cbl {
31 class Query;
32 class ResultSet;
34
36 class Query : private RefCounted {
37 public:
51 Query(const Database& db, CBLQueryLanguage language, std::string_view queryString) {
52 CBLError error;
53 auto q = CBLDatabase_CreateQuery(db.ref(), language, slice(queryString), nullptr, &error);
54 internal::check(q, error);
55 _ref = (CBLRefCounted*)q;
56 }
57
64 inline std::vector<std::string> columnNames() const;
65
76
78 fleece::Dict parameters() const {return CBLQuery_Parameters(ref());}
79
81 inline ResultSet execute();
82
87 std::string explain() {
88 return fleece::alloc_slice(CBLQuery_Explain(ref())).asString();
89 }
90
91 // Change listener (live query):
92
93 class ChangeListener;
94 class Change;
95
104 [[nodiscard]] inline ChangeListener addChangeListener(ListenerToken<Change>::Callback callback);
105
106 private:
107 static void _callListener(void *context, CBLQuery*, CBLListenerToken* token);
109 };
110
111
113 class Result {
114 public:
115
117 uint64_t count() const {
119 }
120
124 return alloc_slice(FLValue_ToJSON((FLValue)dict));
125 }
126
130 fleece::Value valueAtIndex(unsigned i) const {
132 }
133
138 fleece::Value valueForKey(std::string_view key) const {
139 return CBLResultSet_ValueForKey(_ref, slice(key));
140 }
141
143 fleece::Value operator[](int i) const {return valueAtIndex(i);}
144
146 fleece::Value operator[](std::string_view key) const {return valueForKey(key);}
147
148 protected:
149 explicit Result(CBLResultSet* _cbl_nullable ref) :_ref(ref) { }
151 friend class ResultSetIterator;
152 };
153
155 class ResultSet : private RefCounted {
156 public:
158
160 inline iterator begin();
161
163 inline iterator end();
164
165 private:
166 static ResultSet adopt(const CBLResultSet *d) {
167 ResultSet rs;
168 rs._ref = (CBLRefCounted*)d;
169 return rs;
170 }
171
172 friend class Query;
174 };
175
179 public:
181 const Result& operator*() const {return _result;}
183 const Result& operator->() const {return _result;}
184
186 bool operator== (const ResultSetIterator &i) const {return _rs == i._rs;}
188 bool operator!= (const ResultSetIterator &i) const {return _rs != i._rs;}
189
192 if (!CBLResultSet_Next(_rs.ref()))
193 _rs = ResultSet{};
194 return *this;
195 }
196 protected:
197 ResultSetIterator() :_rs(), _result(nullptr) { }
199 :_rs(rs), _result(_rs.ref())
200 {
201 ++*this; // CBLResultSet_Next() has to be called first
202 }
203
206 friend class ResultSet;
207 };
208
209 // Method implementations:
210
211 inline std::vector<std::string> Query::columnNames() const {
212 unsigned n = CBLQuery_ColumnCount(ref());
213 std::vector<std::string> cols;
214 cols.reserve(n);
215 for (unsigned i = 0; i < n ; ++i) {
216 fleece::slice name = CBLQuery_ColumnName(ref(), i);
217 cols.push_back(name.asString());
218 }
219 return cols;
220 }
221
223 CBLError error;
224 auto rs = CBLQuery_Execute(ref(), &error);
225 internal::check(rs, error);
226 return ResultSet::adopt(rs);
227 }
228
232 class Query::ChangeListener : public ListenerToken<Change> {
233 public:
236
241 :ListenerToken<Change>(cb)
242 ,_query(std::move(query))
243 { }
244
248 if (!_query) {
249 throw std::runtime_error("Not allowed to call on uninitialized ChangeListeners");
250 }
251 return getResults(_query, token());
252 }
253
254 private:
255 static ResultSet getResults(Query query, CBLListenerToken* token) {
256 CBLError error;
257 auto rs = CBLQuery_CopyCurrentResults(query.ref(), token, &error);
258 internal::check(rs, error);
259 return ResultSet::adopt(rs);
260 }
261
262 Query _query;
263 friend Change;
264 };
265
268 public:
270 Change(const Change& src) : _query(src._query), _token(src._token) {}
271
274 return ChangeListener::getResults(_query, _token);
275 }
276
279 return _query;
280 }
281
282 private:
283 friend class Query;
284 Change(Query q, CBLListenerToken* token) : _query(q), _token(token) {}
285
286 Query _query;
287 CBLListenerToken* _token;
288 };
289
290
292 auto l = ChangeListener(*this, f);
293 l.setToken( CBLQuery_AddChangeListener(ref(), &_callListener, l.context()) );
294 return l;
295 }
296
297
298 inline void Query::_callListener(void *context, CBLQuery *q, CBLListenerToken* token) {
299 ChangeListener::call(context, Change{Query(q), token});
300 }
301
302
304 return iterator(*this);
305 }
306
308 return iterator();
309 }
310
311 // Query
312
313 Query Database::createQuery(CBLQueryLanguage language, std::string_view queryString) {
314 return Query(*this, language, queryString);
315 }
316}
317
#define CBL_REFCOUNTED_BOILERPLATE(CLASS, SUPER, C_TYPE)
Definition Base.hh:160
#define _cbl_nullable
#define CBL_ASSUME_NONNULL_END
#define CBL_ASSUME_NONNULL_BEGIN
A Couchbase Lite database, which is a container for collections of documents.
Definition Database.hh:147
CBLDatabase *_Nullable ref() const
Returns a pointer to the underlying C object (CBLDatabase), or NULL if this is a null reference.
Definition Database.hh:411
Query createQuery(QueryLanguage language, std::string_view queryString)
Creates a new query by compiling the input string.
Definition Query.hh:313
static void call(void *_Nullable context, Args... args)
Definition Base.hh:228
CBLListenerToken *_Nullable token() const
Definition Base.hh:221
std::function< void(Args...)> Callback
The type of the user callback that this token holds.
Definition Base.hh:180
The change passed to a live query's listener callback, giving access to the updated results.
Definition Query.hh:267
ResultSet results()
Returns the query's results as of this change.
Definition Query.hh:273
friend class Query
Definition Query.hh:283
Query query()
Returns the query that produced this change.
Definition Query.hh:278
Change(const Change &src)
Copy constructor.
Definition Query.hh:270
The token returned by Query::addChangeListener for a live query.
Definition Query.hh:232
ChangeListener(Query query, Callback cb)
Creates a change listener token bound to a specific query and callback.
Definition Query.hh:240
ChangeListener()
Creates an empty, uninitialized change listener token.
Definition Query.hh:235
ResultSet results()
Returns the most recent results computed by the live query.
Definition Query.hh:247
A database query.
Definition Query.hh:36
std::vector< std::string > columnNames() const
Returns the column names that will appear in the query results.
Definition Query.hh:211
CBLQuery *_Nullable ref() const
Returns a pointer to the underlying C object (CBLQuery), or NULL if this is a null reference.
Definition Query.hh:108
fleece::Dict parameters() const
Returns the query's current parameter bindings, if any.
Definition Query.hh:78
Query() noexcept
Constructs a null reference (one that points to no object).
Definition Query.hh:108
ChangeListener addChangeListener(ListenerToken< Change >::Callback callback)
Registers a change listener callback to the query, turning it into a "live query" until the listener ...
Definition Query.hh:291
ResultSet execute()
Runs the query, returning the results.
Definition Query.hh:222
std::string explain()
Returns information about the query, including the translated SQLite form, and the search strategy.
Definition Query.hh:87
Query(const Database &db, CBLQueryLanguage language, std::string_view queryString)
Creates a new query by compiling the input string.
Definition Query.hh:51
void setParameters(fleece::Dict parameters)
Assigns values to the query's parameters.
Definition Query.hh:75
A single query result; ResultSet::iterator iterates over these.
Definition Query.hh:113
fleece::Value operator[](int i) const
A subscript operator that returns value of a column of the current result, given its (zero-based) num...
Definition Query.hh:143
fleece::Value valueForKey(std::string_view key) const
Returns the value of a column of the current result, given its column name.
Definition Query.hh:138
CBLResultSet *_Nullable _ref
Definition Query.hh:150
friend class ResultSetIterator
Definition Query.hh:151
alloc_slice toJSON() const
Returns the current result as a JSON dictionary string.
Definition Query.hh:122
Result(CBLResultSet *_Nullable ref)
Definition Query.hh:149
fleece::Value valueAtIndex(unsigned i) const
Returns the value of a column of the current result, given its (zero-based) numeric index.
Definition Query.hh:130
fleece::Value operator[](std::string_view key) const
A subscript operator that returns the value of a column of the current result, given its column name.
Definition Query.hh:146
uint64_t count() const
Returns the number of columns in the current result.
Definition Query.hh:117
The results of a query.
Definition Query.hh:155
iterator end()
Returns an iterator marking the end of the results.
Definition Query.hh:307
friend class Query
Definition Query.hh:172
ResultSet() noexcept
Constructs a null reference (one that points to no object).
Definition Query.hh:173
iterator begin()
Returns an iterator positioned at the first result.
Definition Query.hh:303
ResultSetIterator iterator
Definition Query.hh:157
Single-pass iterator over a ResultSet, yielding each Result in turn.
Definition Query.hh:178
const Result & operator*() const
Returns the current Result.
Definition Query.hh:181
ResultSetIterator()
Definition Query.hh:197
ResultSetIterator & operator++()
Advances to the next result, or to end-of-results if there are no more.
Definition Query.hh:191
friend class ResultSet
Definition Query.hh:206
const Result & operator->() const
Allows access to the current Result via ->.
Definition Query.hh:183
ResultSet _rs
Definition Query.hh:204
bool operator!=(const ResultSetIterator &i) const
Returns true if the iterators differ.
Definition Query.hh:188
ResultSetIterator(ResultSet rs)
Definition Query.hh:198
Result _result
Definition Query.hh:205
bool operator==(const ResultSetIterator &i) const
Returns true if both iterators reference the same underlying result set position.
Definition Query.hh:186
FLEECE_PUBLIC FLStringResult FLValue_ToJSON(FLValue FL_NULLABLE)
struct CBLListenerToken CBLListenerToken
FLDict _cbl_nullable CBLQuery_Parameters(const CBLQuery *query)
CBLQuery * CBLResultSet_GetQuery(const CBLResultSet *rs)
void CBLQuery_SetParameters(CBLQuery *query, FLDict parameters)
_cbl_warn_unused FLSliceResult CBLQuery_Explain(const CBLQuery *)
FLSlice CBLQuery_ColumnName(const CBLQuery *, unsigned columnIndex)
FLValue _cbl_nullable CBLResultSet_ValueForKey(const CBLResultSet *, FLString key)
CBLQueryLanguage
FLDict CBLResultSet_ResultDict(const CBLResultSet *)
_cbl_warn_unused CBLResultSet *_cbl_nullable CBLQuery_Execute(CBLQuery *, CBLError *_cbl_nullable outError)
_cbl_warn_unused bool CBLResultSet_Next(CBLResultSet *)
struct CBLQuery CBLQuery
struct CBLResultSet CBLResultSet
_cbl_warn_unused CBLQuery *_cbl_nullable CBLDatabase_CreateQuery(const CBLDatabase *db, CBLQueryLanguage language, FLString queryString, int *_cbl_nullable outErrorPos, CBLError *_cbl_nullable outError)
FLValue _cbl_nullable CBLResultSet_ValueAtIndex(const CBLResultSet *, unsigned index)
_cbl_warn_unused CBLListenerToken * CBLQuery_AddChangeListener(CBLQuery *query, CBLQueryChangeListener listener, void *_cbl_nullable context)
_cbl_warn_unused CBLResultSet *_cbl_nullable CBLQuery_CopyCurrentResults(const CBLQuery *query, CBLListenerToken *listener, CBLError *_cbl_nullable outError)
unsigned CBLQuery_ColumnCount(const CBLQuery *)
struct CBLRefCounted CBLRefCounted
const struct _FLDict * FLDict
const struct _FLValue * FLValue
Definition Base.hh:46
fleece::slice slice
Convenience alias for fleece::slice, a non-owning view of a byte range.
Definition Base.hh:49
fleece::alloc_slice alloc_slice
Convenience alias for fleece::alloc_slice, an owning byte buffer.
Definition Base.hh:51