Couchbase Lite C++
Couchbase Lite C++ API
Loading...
Searching...
No Matches
Database.hh
Go to the documentation of this file.
1//
2// Database.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++/Base.hh"
21#include "cbl/CBLCollection.h"
22#include "cbl/CBLDatabase.h"
23#include "cbl/CBLDocument.h"
24#include "cbl/CBLQuery.h"
25#include "cbl/CBLLog.h"
26#include "cbl/CBLScope.h"
27#include "fleece/Fleece.hh"
28#include "fleece/Mutable.hh"
29#include <exception>
30#include <functional>
31#include <mutex>
32#include <optional>
33#include <string>
34#include <string_view>
35#include <vector>
36
37
39
40namespace cbl {
41 class Blob;
42 class Collection;
43 class Document;
44 class MutableDocument;
45 class Query;
46
48 using ConflictHandler = std::function<bool(MutableDocument documentBeingSaved,
49 Document conflictingDocument)>;
50
51
52#ifdef COUCHBASE_ENTERPRISE
55 class Extension {
56 public:
61 static void enableVectorSearch(std::string_view path) {
62 CBLError error {};
63 internal::check(CBL_EnableVectorSearch(slice(path), &error), error);
64 }
65 };
66
71
76 public:
81
87
93 EncryptionKey(std::string_view password, bool old = false) {
94 if ( old ) CBLEncryptionKey_FromPasswordOld(this, slice(password));
95 else CBLEncryptionKey_FromPassword(this, slice(password));
96 }
97
100 CBLEncryptionKey::operator=(k);
101 return *this;
102 }
103 };
104
105#endif
106
109 public:
110 std::string directory;
111 #ifdef COUCHBASE_ENTERPRISE
113 #endif
123 bool fullSync{false};
124
129 directory = ((slice)cblConfig.directory).asString();
130#ifdef COUCHBASE_ENTERPRISE
131 encryptionKey = cblConfig.encryptionKey;
132#endif
133 fullSync = cblConfig.fullSync;
134 }
135
138
144 };
145
147 class Database : private RefCounted {
148 public:
149 // Static database-file operations:
150
155 static bool exists(std::string_view name, std::optional<std::string_view> inDirectory=std::nullopt) {
156 slice inDir;
157 if ( inDirectory ) inDir = slice(*inDirectory);
158 return CBL_DatabaseExists(slice(name), inDir);
159 }
160
165 static void copyDatabase(std::string_view fromPath,
166 std::string_view toName)
167 {
168 CBLError error;
169 internal::check( CBL_CopyDatabase(slice(fromPath), slice(toName),
170 nullptr, &error), error );
171 }
172
178 static void copyDatabase(std::string_view fromPath,
179 std::string_view toName,
181 {
182 CBLError error;
183 CBLDatabaseConfiguration cblConfig{
184 (slice)config.directory,
185#ifdef COUCHBASE_ENTERPRISE
186 config.encryptionKey,
187#endif
188 config.fullSync
189 };
190 internal::check( CBL_CopyDatabase(slice(fromPath), slice(toName),
191 &cblConfig, &error), error );
192 }
193
198 static void deleteDatabase(std::string_view name, std::optional<std::string_view> inDirectory =std::nullopt) {
199 CBLError error;
200 slice inDir;
201 if ( inDirectory ) inDir = slice(*inDirectory);
202 if (!CBL_DeleteDatabase(slice(name), inDir, &error) && error.code != 0)
203 internal::check(false, error);
204 }
205
206 // Lifecycle:
207
212 Database(std::string_view name) {
213 open(name, nullptr);
214 }
215
221 Database(std::string_view name,
223 {
224 CBLDatabaseConfiguration cblConfig{
225 (slice)config.directory,
226#ifdef COUCHBASE_ENTERPRISE
227 config.encryptionKey,
228#endif
229 config.fullSync
230 };
231 open(name, &cblConfig);
232 }
233
235 void close() {
236 CBLError error;
237 internal::check(CBLDatabase_Close(ref(), &error), error);
238 }
239
242 CBLError error;
243 internal::check(CBLDatabase_Delete(ref(), &error), error);
244 }
245
249 CBLError error;
250 internal::check(CBLDatabase_PerformMaintenance(ref(), type, &error), error);
251 }
252
253#ifdef COUCHBASE_ENTERPRISE
260 CBLError error{};
261 internal::check(CBLDatabase_ChangeEncryptionKey(ref(), newKey, &error), error);
262 }
263#endif
264
265 // Accessors:
266
268 std::string name() const {return internal::asString(CBLDatabase_Name(ref()));}
269
271 std::string path() const {return internal::asString(CBLDatabase_Path(ref()));}
272
275
288 inline Blob getBlob(fleece::Dict properties) const;
289
302 inline void saveBlob(const Blob& blob);
303
304 // Collections:
305
310 fleece::MutableArray getScopeNames() const {
311 CBLError error {};
312 FLMutableArray flNames = CBLDatabase_ScopeNames(ref(), &error);
313 internal::check(error.code == 0, error);
314 fleece::MutableArray names(flNames);
315 FLMutableArray_Release(flNames);
316 return names;
317 }
318
322 fleece::MutableArray getCollectionNames(std::string_view scopeName = (std::string_view)slice(kCBLDefaultScopeName)) const {
323 CBLError error {};
324 FLMutableArray flNames = CBLDatabase_CollectionNames(ref(), slice(scopeName), &error);
325 internal::check(error.code == 0, error);
326 fleece::MutableArray names(flNames);
327 FLMutableArray_Release(flNames);
328 return names;
329 }
330
337 inline Collection getCollection(std::string_view collectionName, std::optional<std::string_view> scopeName = std::nullopt) const;
338
349 inline Collection createCollection(std::string_view collectionName, std::optional<std::string_view> scopeName =std::nullopt);
350
355 void deleteCollection(std::string_view collectionName, std::optional<std::string_view> scopeName =std::nullopt) {
356 CBLError error {};
357 slice sname = scopeName.value_or(slice(kCBLDefaultScopeName));
358 if ( scopeName ) sname = *scopeName;
359 internal::check(CBLDatabase_DeleteCollection(ref(), slice(collectionName), sname, &error), error);
360 }
361
363 inline Collection getDefaultCollection() const;
364
365 // Query:
366
377 inline Query createQuery(QueryLanguage language, std::string_view queryString);
378
379 // Notifications:
380
381 using NotificationsReadyCallback = std::function<void(Database)>;
382
388 _notificationReadyCallbackAccess->setCallback(callback);
389 CBLDatabase_BufferNotifications(ref(), [](void *context, CBLDatabase *db) {
390 ((NotificationsReadyCallbackAccess*)context)->call(Database(db));
391 }, _notificationReadyCallbackAccess.get());
392 }
393
398
399 // Destructors:
400
404 clear();
405 }
406
407 protected:
408 friend class Collection;
409 friend class Scope;
410
412
413 private:
414 void open(std::string_view name, const CBLDatabaseConfiguration* _cbl_nullable config) {
415 CBLError error {};
416 _ref = (CBLRefCounted*)CBLDatabase_Open(slice(name), config, &error);
417 internal::check(_ref != nullptr, error);
418
419 _notificationReadyCallbackAccess = std::make_shared<NotificationsReadyCallbackAccess>();
420 }
421
422 class NotificationsReadyCallbackAccess {
423 public:
424 void setCallback(NotificationsReadyCallback callback) {
425 std::lock_guard<std::mutex> lock(_mutex);
426 _callback = callback;
427 }
428
429 void call(Database db) {
431 {
432 std::lock_guard<std::mutex> lock(_mutex);
433 callback = _callback;
434 }
435 if (callback)
436 callback(db);
437 }
438 private:
439 std::mutex _mutex;
440 NotificationsReadyCallback _callback {nullptr};
441 };
442
443 std::shared_ptr<NotificationsReadyCallbackAccess> _notificationReadyCallbackAccess;
444
445 public:
449 Database(const Database &other) noexcept
450 :RefCounted(other)
451 ,_notificationReadyCallbackAccess(other._notificationReadyCallbackAccess)
452 { }
453
456 Database(Database &&other) noexcept
457 :RefCounted((RefCounted&&)other)
458 ,_notificationReadyCallbackAccess(std::move(other._notificationReadyCallbackAccess))
459 { }
460
464 Database& operator=(const Database &other) noexcept {
465 RefCounted::operator=(other);
466 _notificationReadyCallbackAccess = other._notificationReadyCallbackAccess;
467 return *this;
468 }
469
473 Database& operator=(Database &&other) noexcept {
474 RefCounted::operator=((RefCounted&&)other);
475 _notificationReadyCallbackAccess = std::move(other._notificationReadyCallbackAccess);
476 return *this;
477 }
478
482 void clear() {
483 // Reset _notificationReadyCallbackAccess the releasing the _ref to
484 // ensure that CBLDatabase is deleted before _notificationReadyCallbackAccess.
485 RefCounted::clear();
486 _notificationReadyCallbackAccess.reset();
487 }
488 };
489
490
496 public:
500 :Transaction(db.ref())
501 { }
502
506 explicit Transaction (CBLDatabase *db) {
507 CBLError error{};
508 internal::check(CBLDatabase_BeginTransaction(db, &error), error);
509 _db = db;
510 }
511
513 void commit() {end(true);}
514
516 void abort() {end(false);}
517
519 ~Transaction() {end(false);}
520
521 private:
522 void end(bool commit) {
523 CBLDatabase *db = _db;
524 if (db) {
525 _db = nullptr;
526 CBLError error;
527 if (!CBLDatabase_EndTransaction(db, commit, &error)) {
528 // If an exception is thrown while a Batch is in scope, its destructor will
529 // call end(). If I'm in this situation I cannot throw another exception or
530 // the C++ runtime will abort the process. Detect this and just warn instead.
531 if (std::current_exception())
533 "Transaction::end failed, while handling an exception");
534 else
535 internal::check(false, error);
536 }
537 }
538 }
539
540 CBLDatabase* _cbl_nullable _db = nullptr;
541 };
542}
543
#define CBL_REFCOUNTED_WITHOUT_COPY_MOVE_BOILERPLATE(CLASS, SUPER, C_TYPE)
Definition Base.hh:140
#define _cbl_nullable
#define CBL_ASSUME_NONNULL_END
#define CBL_ASSUME_NONNULL_BEGIN
A reference to a binary data blob associated with a document.
Definition Blob.hh:39
A Collection is a container for documents within a database.
Definition Collection.hh:131
Database configuration options.
Definition Database.hh:108
std::string directory
The parent directory of the database.
Definition Database.hh:110
EncryptionKey encryptionKey
The database's encryption key (if any)
Definition Database.hh:112
DatabaseConfiguration(const CBLDatabaseConfiguration &cblConfig)
Constructs a configuration from a C CBLDatabaseConfiguration, copying the directory and (in EE) encry...
Definition Database.hh:128
static DatabaseConfiguration defaultConfiguration()
Returns a configuration initialized with the default settings (default directory, no encryption,...
Definition Database.hh:141
DatabaseConfiguration()=default
Default constructor: empty directory, no encryption, full-sync off.
bool fullSync
As Couchbase Lite normally configures its databases, There is a very small (though non-zero) chance t...
Definition Database.hh:123
A Couchbase Lite database, which is a container for collections of documents.
Definition Database.hh:147
void saveBlob(const Blob &blob)
Save a new Blob object into the database without associating it with any documents.
Definition Blob.hh:230
~Database()
Releases the underlying database handle.
Definition Database.hh:403
void sendNotifications()
Immediately issues all pending notifications for this database, by calling their listener callbacks.
Definition Database.hh:395
Blob getBlob(fleece::Dict properties) const
Get a Blob from the database using the Blob properties.
Definition Blob.hh:221
fleece::MutableArray getCollectionNames(std::string_view scopeName=(std::string_view) slice(kCBLDefaultScopeName)) const
Returns the names of all collections in the scope.
Definition Database.hh:322
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
std::function< void(Database)> NotificationsReadyCallback
Definition Database.hh:381
std::string path() const
Returns the database's full filesystem path, or an empty string if the database is closed or deleted.
Definition Database.hh:271
void clear()
Releases the underlying C CBLDatabase handle and drops the buffered-notification callback.
Definition Database.hh:482
void bufferNotifications(NotificationsReadyCallback callback)
Switches the database to buffered-notification mode.
Definition Database.hh:387
Collection getDefaultCollection() const
Returns the default collection.
Definition Collection.hh:438
Collection getCollection(std::string_view collectionName, std::optional< std::string_view > scopeName=std::nullopt) const
Returns the existing collection with the given name and scope.
Definition Collection.hh:426
std::string name() const
Returns the database's name.
Definition Database.hh:268
static void copyDatabase(std::string_view fromPath, std::string_view toName, const DatabaseConfiguration &config)
Copies a database file to a new location, and assigns it a new internal UUID to distinguish it from t...
Definition Database.hh:178
Database(Database &&other) noexcept
Move constructor.
Definition Database.hh:456
Collection createCollection(std::string_view collectionName, std::optional< std::string_view > scopeName=std::nullopt)
Create a new collection.
Definition Collection.hh:432
friend class Collection
Definition Database.hh:408
Database(std::string_view name, const DatabaseConfiguration &config)
Opens a database, or creates it if it doesn't exist yet, returning a new Database instance.
Definition Database.hh:221
Database & operator=(Database &&other) noexcept
Move assignment.
Definition Database.hh:473
void deleteCollection(std::string_view collectionName, std::optional< std::string_view > scopeName=std::nullopt)
Delete an existing collection.
Definition Database.hh:355
friend class Scope
Definition Database.hh:409
static void deleteDatabase(std::string_view name, std::optional< std::string_view > inDirectory=std::nullopt)
Deletes a database file.
Definition Database.hh:198
Database() noexcept
Constructs a null reference (one that points to no object).
Definition Database.hh:411
void performMaintenance(CBLMaintenanceType type)
Performs database maintenance.
Definition Database.hh:248
void deleteDatabase()
Closes and deletes a database.
Definition Database.hh:241
static void copyDatabase(std::string_view fromPath, std::string_view toName)
Copies a database file to a new location, and assigns it a new internal UUID to distinguish it from t...
Definition Database.hh:165
fleece::MutableArray getScopeNames() const
Returns the names of all existing scopes in the database.
Definition Database.hh:310
static bool exists(std::string_view name, std::optional< std::string_view > inDirectory=std::nullopt)
Returns true if a database with the given name exists in the given directory.
Definition Database.hh:155
void close()
Closes an open database.
Definition Database.hh:235
DatabaseConfiguration config() const
Returns the database's configuration, as given when it was opened.
Definition Database.hh:274
Database & operator=(const Database &other) noexcept
Copy assignment.
Definition Database.hh:464
Database(std::string_view name)
Opens a database, or creates it if it doesn't exist yet, returning a new Database instance.
Definition Database.hh:212
void changeEncryptionKey(const EncryptionKey *_Nullable newKey)
Encrypts or decrypts a database, or changes its encryption key.
Definition Database.hh:259
Database(const Database &other) noexcept
Copy constructor.
Definition Database.hh:449
An immutable, in-memory copy of a document read from a collection.
Definition Document.hh:33
A database encryption key, used in DatabaseConfiguration to open or create an encrypted database.
Definition Database.hh:75
EncryptionKey(const CBLEncryptionKey &k)
Creates a key from an existing C CBLEncryptionKey.
Definition Database.hh:84
EncryptionKey & operator=(const CBLEncryptionKey &k)
Assigns from an existing C CBLEncryptionKey.
Definition Database.hh:99
EncryptionKey(std::string_view password, bool old=false)
Derives an AES-256 key from a password.
Definition Database.hh:93
EncryptionKey()
Creates an empty key (algorithm kCBLEncryptionNone, i.e.
Definition Database.hh:78
Manages Couchbase Lite extensions, such as the Vector Search extension.
Definition Database.hh:55
static void enableVectorSearch(std::string_view path)
Enables Vector Search extension by specifying the extension path to search for the Vector Search exte...
Definition Database.hh:61
A mutable document, whose properties can be modified and saved to a collection.
Definition Document.hh:104
A database query.
Definition Query.hh:36
void commit()
Commits changes and ends the transaction.
Definition Database.hh:513
Transaction(Database db)
Begins a batch operation on the database that will end when the Batch instance goes out of scope.
Definition Database.hh:499
void abort()
Ends the transaction, rolling back changes.
Definition Database.hh:516
Transaction(CBLDatabase *db)
Begins a batch operation on the given C database handle.
Definition Database.hh:506
~Transaction()
Ends the transaction, rolling back any changes that have not been committed.
Definition Database.hh:519
kCBLLogDomainDatabase
kCBLLogWarning
void FLMutableArray_Release(FLMutableArray FL_NULLABLE d)
bool CBLDatabase_DeleteCollection(CBLDatabase *db, FLString collectionName, FLString scopeName, CBLError *_cbl_nullable outError)
FLMutableArray _cbl_nullable CBLDatabase_CollectionNames(const CBLDatabase *db, FLString scopeName, CBLError *_cbl_nullable outError)
FLMutableArray _cbl_nullable CBLDatabase_ScopeNames(const CBLDatabase *db, CBLError *_cbl_nullable outError)
bool CBL_CopyDatabase(FLString fromPath, FLString toName, const CBLDatabaseConfiguration *_cbl_nullable config, CBLError *_cbl_nullable outError)
bool CBLDatabase_EndTransaction(CBLDatabase *, bool commit, CBLError *_cbl_nullable outError)
struct CBLDatabase CBLDatabase
bool CBLEncryptionKey_FromPassword(CBLEncryptionKey *key, FLString password)
bool CBLDatabase_Delete(CBLDatabase *, CBLError *_cbl_nullable outError)
bool CBLDatabase_Close(CBLDatabase *, CBLError *_cbl_nullable outError)
bool CBL_DatabaseExists(FLString name, FLString inDirectory)
bool CBLDatabase_ChangeEncryptionKey(CBLDatabase *, const CBLEncryptionKey *_cbl_nullable newKey, CBLError *outError)
_cbl_warn_unused CBLDatabase *_cbl_nullable CBLDatabase_Open(FLSlice name, const CBLDatabaseConfiguration *_cbl_nullable config, CBLError *_cbl_nullable outError)
bool CBL_DeleteDatabase(FLString name, FLString inDirectory, CBLError *_cbl_nullable outError)
const CBLDatabaseConfiguration CBLDatabase_Config(const CBLDatabase *)
CBLEncryptionAlgorithm
bool CBLDatabase_PerformMaintenance(CBLDatabase *db, CBLMaintenanceType type, CBLError *_cbl_nullable outError)
_cbl_warn_unused FLStringResult CBLDatabase_Path(const CBLDatabase *)
CBLDatabaseConfiguration CBLDatabaseConfiguration_Default(void)
CBLMaintenanceType
bool CBLDatabase_BeginTransaction(CBLDatabase *, CBLError *_cbl_nullable outError)
bool CBL_EnableVectorSearch(FLString path, CBLError *_cbl_nullable outError)
bool CBLEncryptionKey_FromPasswordOld(CBLEncryptionKey *key, FLString password)
CBLEncryptionKeySize
FLString CBLDatabase_Name(const CBLDatabase *)
void CBLDatabase_SendNotifications(CBLDatabase *db)
void CBLDatabase_BufferNotifications(CBLDatabase *db, CBLNotificationsReadyCallback _cbl_nullable callback, void *_cbl_nullable context)
void CBL_Log(CBLLogDomain domain, CBLLogLevel level, const char *format,...) __printflike(3
struct CBLRefCounted CBLRefCounted
CBL_PUBLIC const FLString kCBLDefaultScopeName
struct _FLArray * FLMutableArray
Definition Base.hh:46
CBLEncryptionKeySize EncryptionKeySize
Alias for the C CBLEncryptionKeySize enum giving the required key size for an algorithm.
Definition Database.hh:70
fleece::slice slice
Convenience alias for fleece::slice, a non-owning view of a byte range.
Definition Base.hh:49
CBLQueryLanguage QueryLanguage
Definition Base.hh:53
CBLEncryptionAlgorithm EncryptionAlgorithm
Alias for the C CBLEncryptionAlgorithm enum identifying an encryption algorithm.
Definition Database.hh:68
std::function< bool(MutableDocument documentBeingSaved, Document conflictingDocument)> ConflictHandler
Conflict handler used when saving a document.
Definition Database.hh:48
CBLEncryptionKey encryptionKey