4#include "Stroika/Foundation/StroikaPreComp.h"
10#include "Stroika/Foundation/Common/GUID.h"
24using namespace Characters;
25using namespace Containers;
27using namespace DataExchange;
28using namespace Database;
29using namespace Database::Document::LocalDocumentDB;
30using namespace Execution;
46 template <InternallySynchronized SYNC_STYLE>
48 conditional_t<SYNC_STYLE == InternallySynchronized::eNotKnownInternallySynchronized, Debug::AssertExternallySynchronizedMutex, recursive_mutex>;
49 static_assert (Common::StdCompat::BasicLockable<MyMaybeLock_<InternallySynchronized::eNotKnownInternallySynchronized>>);
50 static_assert (Common::StdCompat::BasicLockable<MyMaybeLock_<InternallySynchronized::eInternallySynchronized>>);
56 template <InternallySynchronized SYNC_STYLE>
66 const shared_ptr<MemoryDatabaseRep_> fConnectionRep_;
69 MyCollectionRep_ (
const shared_ptr<MemoryDatabaseRep_>& connectionRep,
const String& collectionName)
70 : fConnectionRep_{connectionRep}
71 , fTableName_{collectionName}
74 virtual String GetName ()
const override
76 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
81#if USE_NOISY_TRACE_IN_THIS_MODULE_
84 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
85 return fConnectionRep_->WrapExecute_ (
87 optional<VariantValue> vID = v.
Lookup (Document::kID);
88 Require (not vID.has_value () or fConnectionRep_->fOptions_.fAddAllowsExternallySpecifiedIDs);
90 CollectionRep_ collection = fConnectionRep_->fCollections_.LookupValue (fTableName_);
93 doc2Add.
Remove (Document::kID);
95 collection.Add (
id, doc2Add);
96 fConnectionRep_->fCollections_.Add (fTableName_, collection);
97 return id.ToString ();
101 virtual optional<Document::Document> Get (
const IDType&
id,
const optional<Projection>& projection)
override
103#if USE_NOISY_TRACE_IN_THIS_MODULE_
106 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
107 return fConnectionRep_->WrapExecute_ (
109 optional<Document::Document> r = fConnectionRep_->fCollections_.LookupValue (fTableName_).Lookup (
GUID{
id});
111 r->Add (Document::kID,
id);
113 if (projection and r) {
114 r = projection->Apply (*r);
122#if USE_NOISY_TRACE_IN_THIS_MODULE_
123 TraceContextBumper ctx{
"LocalDocumentDB::MemoryDatabaseRep_::MyCollectionRep_::GetAll",
"filter={}, projection={}"_f, filter, projection};
125 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
126 return fConnectionRep_->WrapExecute_ (
128 return fConnectionRep_->fCollections_.LookupValue (fTableName_)
132 d.
Add (Document::kID, kvp.fKey.ToString ());
133 if (filter and not filter->Matches (d)) {
138 d = projection->
Apply (d);
148#if USE_NOISY_TRACE_IN_THIS_MODULE_
149 TraceContextBumper ctx{
"LocalDocumentDB::MemoryDatabaseRep_::MyCollectionRep_::Update"};
151 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
152 fConnectionRep_->WrapExecute_ (
155 if (onlyTheseFields) {
160 CollectionRep_ collection = fConnectionRep_->fCollections_.LookupChecked (fTableName_, kExcept1_);
163 if (onlyTheseFields) {
164 d2Update.
AddAll (uploadDoc);
169 collection.Add (
id, d2Update);
170 fConnectionRep_->fCollections_.Add (fTableName_, collection);
174 virtual void Remove (
const IDType&
id)
override
176#if USE_NOISY_TRACE_IN_THIS_MODULE_
177 TraceContextBumper ctx{
"LocalDocumentDB::MemoryDatabaseRep_::MyCollectionRep_::Remove"};
179 scoped_lock critSec{fConnectionRep_->fMaybeLock_};
180 fConnectionRep_->WrapExecute_ (
182 if (optional<CollectionRep_> oc = fConnectionRep_->fCollections_.Lookup (fTableName_)) {
183 CollectionRep_ c = *oc;
184 if (c.RemoveIf (id)) {
185 fConnectionRep_->fCollections_.Add (fTableName_, c);
194 virtual void Commit ()
override
204 return Disposition::eCompleted;
208 MemoryDatabaseRep_ () =
delete;
209 MemoryDatabaseRep_ (
const MemoryDatabaseRep_&) =
delete;
216 virtual shared_ptr<const EngineProperties> GetEngineProperties ()
const override
219 virtual String GetEngineName ()
const override
221 return "LocalDocumentDB.MemoryDB"sv;
224 static const shared_ptr<const EngineProperties> kProps_ = Memory::MakeSharedPtr<const MyEngineProperties_> ();
227 virtual Database::Document::Connection::Options GetOptions ()
const override
233 switch (vv.GetType ()) {
234 case VariantValue::Type::eBLOB:
236 case VariantValue::Type::eString:
238 case VariantValue::Type::eFloat:
239 return sizeof (
long double);
246 virtual uintmax_t GetSpaceConsumed ()
const override
248 uintmax_t totalSize{};
251 totalSize += ci.fKey.size () + 3;
255 totalSize += xi.fKey.size () + 3;
256 totalSize += EstimateSize_ (xi.fValue) + 4;
264 scoped_lock declareContext{fMaybeLock_};
269 scoped_lock declareContext{fMaybeLock_};
270 if (not fCollections_.
Lookup (name)) {
271 fCollections_.
Add (name, {});
273 return GetCollection (name);
275 virtual void DropCollection (
const String& name)
override
277 scoped_lock declareContext{fMaybeLock_};
282 scoped_lock declareContext{fMaybeLock_};
285 Memory::MakeSharedPtr<MyCollectionRep_> (Debug::UncheckedDynamicPointerCast<MemoryDatabaseRep_> (shared_from_this ()), name)};
291 virtual void Flush ()
override
295 template <
typename FUN>
296 inline auto WrapExecute_ (FUN&& f,
const optional<String>& collectionName,
bool write) -> invoke_result_t<FUN>
298 return Document::Connection::Private_::WrapLoggingExecuteHelper_ (forward<FUN> (f),
this, fOptions_, collectionName, write);
306 template <InternallySynchronized SYNC_STYLE>
309 const filesystem::path fExternalFile_;
310 shared_ptr<MemoryDatabaseRep_<SYNC_STYLE>> fMemoryDB_;
313 const bool fFlushOnEachWrite_;
315 const bool fReadOnly_{
false};
317#if qStroika_Foundation_Common_Platform_Windows
318 const optional<Time::DurationSeconds> fRetryOnSharingViolationFor_;
322 const shared_ptr<SingleFileDatabaseRep_> fDBRep_;
324 shared_ptr<Database::Document::Collection::IRep> fDelegateToInMemoryDB_;
326 MyCollectionRep_ (
const shared_ptr<SingleFileDatabaseRep_>& dbRep,
const String& name,
327 const shared_ptr<Database::Document::Collection::IRep>& delgateImplTo)
330 , fDelegateToInMemoryDB_{delgateImplTo}
333 virtual String GetName ()
const override
339#if USE_NOISY_TRACE_IN_THIS_MODULE_
340 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::MyCollectionRep_::Add"};
342 scoped_lock critSec{fDBRep_->fMemoryDB_->fMaybeLock_};
343 return fDBRep_->WrapExecute_ (
345 auto id = fDelegateToInMemoryDB_->Add (v);
346 fDBRep_->DataChangedSoMaybeWrite2Disk ();
351 virtual optional<Document::Document> Get (
const IDType&
id,
const optional<Projection>& projection)
override
353#if USE_NOISY_TRACE_IN_THIS_MODULE_
354 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::MyCollectionRep_::Get"};
356 scoped_lock critSec{fDBRep_->fMemoryDB_->fMaybeLock_};
357 return fDBRep_->WrapExecute_ ([&] () {
return fDelegateToInMemoryDB_->Get (
id, projection); }, fName_,
false);
361#if USE_NOISY_TRACE_IN_THIS_MODULE_
362 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::MyCollectionRep_::GetAll",
"filter={}, projection={}"_f,
365 return fDBRep_->WrapExecute_ ([&] () {
return fDelegateToInMemoryDB_->GetAll (filter, projection); }, fName_,
false);
369#if USE_NOISY_TRACE_IN_THIS_MODULE_
370 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::MyCollectionRep_::Update"};
372 scoped_lock critSec{fDBRep_->fMemoryDB_->fMaybeLock_};
373 fDBRep_->WrapExecute_ (
375 fDelegateToInMemoryDB_->Update (
id, newV, onlyTheseFields);
376 fDBRep_->DataChangedSoMaybeWrite2Disk ();
380 virtual void Remove (
const IDType&
id)
override
382#if USE_NOISY_TRACE_IN_THIS_MODULE_
383 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::MyCollectionRep_::Remove"};
385 scoped_lock critSec{fDBRep_->fMemoryDB_->fMaybeLock_};
386 fDBRep_->WrapExecute_ (
388 fDelegateToInMemoryDB_->Remove (
id);
389 fDBRep_->DataChangedSoMaybeWrite2Disk ();
396 virtual void Commit ()
override
400 virtual void Rollback ()
override
404 virtual Disposition GetDisposition ()
const override
406 return Disposition::eCompleted;
412 o.fOperationLoggingCallback =
nullptr;
416 SingleFileDatabaseRep_ () =
delete;
417 SingleFileDatabaseRep_ (
const SingleFileDatabaseRep_&) =
delete;
419 const Document::LocalDocumentDB::Options::SingleFileStorage& sfOptions)
420 : fExternalFile_{sfOptions.fFile}
421 , fMemoryDB_{make_shared<MemoryDatabaseRep_<SYNC_STYLE>> (stripOptionsForMemDB_ (options))}
422 , fReader_{get<DataExchange::Variant::Reader> (sfOptions.fSerialization)}
423 , fWriter_{get<DataExchange::Variant::Writer> (sfOptions.fSerialization)}
424 , fFlushOnEachWrite_{sfOptions.fFlushOnEachWrite}
425 , fDirty_{not fFlushOnEachWrite_}
426 , fReadOnly_{sfOptions.fReadOnly}
427 , fOperationLoggingCallback_{options.fOperationLoggingCallback}
428#if qStroika_Foundation_Common_Platform_Windows
429 , fRetryOnSharingViolationFor_{sfOptions.fRetryOnSharingViolationFor}
432 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::SingleFileDatabaseRep_"};
433 if (not sfOptions.fForceCreateNew) {
437 virtual ~SingleFileDatabaseRep_ ()
override
443 virtual shared_ptr<const EngineProperties> GetEngineProperties ()
const override
446 virtual String GetEngineName ()
const override
448 return "LocalDocumentDB.SingleFile"sv;
451 static const shared_ptr<const EngineProperties> kProps_ = Memory::MakeSharedPtr<const MyEngineProperties_> ();
454 virtual Database::Document::Connection::Options GetOptions ()
const override
456 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
457 Database::Document::Connection::Options o = fMemoryDB_->GetOptions ();
458 o.fOperationLoggingCallback = fOperationLoggingCallback_;
461 virtual uintmax_t GetSpaceConsumed ()
const override
464 IgnoreExceptionsExceptThreadAbortForCall (
const_cast<SingleFileDatabaseRep_*
> (
this)->DoWriteToFS ());
466 error_code ignoredEC;
467 return filesystem::file_size (fExternalFile_, ignoredEC);
471 return fMemoryDB_->GetCollections ();
475 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
476 return WrapExecute_ (
478 fMemoryDB_->CreateCollection (name);
479 DataChangedSoMaybeWrite2Disk ();
480 return GetCollection (name);
484 virtual void DropCollection (
const String& name)
override
486 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
489 fMemoryDB_->DropCollection (name);
490 DataChangedSoMaybeWrite2Disk ();
496 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
499 Debug::UncheckedDynamicPointerCast<SingleFileDatabaseRep_> (shared_from_this ()), name, memDBCollection)};
505 virtual void Flush ()
override
511 using namespace IO::FileSystem;
512#if USE_NOISY_TRACE_IN_THIS_MODULE_
513 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::DoReadFromFS",
"path={}"_f, fExternalFile_};
515 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
516 if (filesystem::exists (fExternalFile_)) {
517 fMemoryDB_->fCollections_.clear ();
520 fMemoryDB_->fCollections_.Add (
521 collectionAndDocument.fKey,
524 return {GUID{kvp.fKey}, kvp.fValue.As<Document::Document> ()};
529 void DataChangedSoMaybeWrite2Disk ()
531 if (fFlushOnEachWrite_) {
540#if USE_NOISY_TRACE_IN_THIS_MODULE_
541 TraceContextBumper ctx{
"LocalDocumentDB::SingleFileDatabaseRep_::DoWriteToFS",
"path={}"_f, fExternalFile_};
543 if (not this->fReadOnly_) {
544 scoped_lock declareContext{fMemoryDB_->fMaybeLock_};
545 using namespace IO::FileSystem;
546 ThroughTmpFileWriter tmpFile{fExternalFile_};
547 IO::FileSystem::FileOutputStream::Ptr outStream = IO::FileSystem::FileOutputStream::New (tmpFile.GetFilePath ());
553 collWithStringKey.
Add (kvp.fKey.ToString (),
VariantValue{kvp.fValue});
555 collectionsAsVV.
Add (collection.fKey,
VariantValue{collWithStringKey});
559#if qStroika_Foundation_Common_Platform_Windows
560 tmpFile.fRetryOnSharingViolationFor = fRetryOnSharingViolationFor_;
566 template <
typename FUN>
567 inline auto WrapExecute_ (FUN&& f,
const optional<String>& collectionName,
bool write) -> invoke_result_t<FUN>
569 if (fOperationLoggingCallback_) {
570 Database::Document::Connection::Options o = fMemoryDB_->GetOptions ();
571 o.fOperationLoggingCallback = fOperationLoggingCallback_;
572 return Document::Connection::Private_::WrapLoggingExecuteHelper_ (forward<FUN> (f),
this, o, collectionName, write);
584 template <InternallySynchronized SYNC_STYLE>
587 const filesystem::path fRoot_;
590#if qStroika_Foundation_Common_Platform_Windows
591 const optional<Time::DurationSeconds> fRetryOnSharingViolationFor_;
595 const shared_ptr<DirectoryFilesystemDatabaseRep_> fDBRep_;
597 const filesystem::path fCollectionRoot_;
599 MyCollectionRep_ (
const shared_ptr<DirectoryFilesystemDatabaseRep_>& dbRep,
const String& name)
602 , fCollectionRoot_{dbRep->GetCollectionFilePath_ (name)}
605 virtual String GetName ()
const override
611#if USE_NOISY_TRACE_IN_THIS_MODULE_
612 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::MyCollectionRep_::Add"};
614 optional<VariantValue> vID = v.
Lookup (Document::kID);
615 Require (not vID.has_value () or fDBRep_->fOptions_.fAddAllowsExternallySpecifiedIDs);
617 fDBRep_->WrapExecute_ (
621 doc2Add.
Remove (Document::kID);
628 virtual optional<Document::Document> Get (
const IDType&
id,
const optional<Projection>& projection)
override
630#if USE_NOISY_TRACE_IN_THIS_MODULE_
631 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::MyCollectionRep_::Get"};
633 return fDBRep_->WrapExecute_ (
634 [&] () -> optional<Document::Document> {
635 if (
auto od = DoReadFromFS_ (
GUID{
id})) {
637 d.
Add (Document::kID,
id);
639 d = projection->
Apply (d);
649#if USE_NOISY_TRACE_IN_THIS_MODULE_
650 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::MyCollectionRep_::GetAll",
651 "filter={}, projection={}"_f, filter, projection};
653 return fDBRep_->WrapExecute_ (
656 for (
const auto& entry : filesystem::directory_iterator{fCollectionRoot_}) {
657 if (entry.path ().extension () ==
".json"sv) {
659 fDBRep_->fReader_.Read (IO::FileSystem::FileInputStream::New (entry.path ())).template As<Document::Document> ();
660 d.
Add (Document::kID, entry.path ().stem ().string ());
661 if (not filter or filter->Matches (d)) {
663 d = projection->
Apply (d);
675#if USE_NOISY_TRACE_IN_THIS_MODULE_
676 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::MyCollectionRep_::Update",
677 "id={},newV={}, onlyTheseFields={}"_f, id, newV, onlyTheseFields};
679 fDBRep_->WrapExecute_ (
682 onlyTheseFields ? Memory::ValueOfOrThrow (DoReadFromFS_ (
id),
RuntimeErrorException{
"no such id"sv}) : newV;
684 if (onlyTheseFields) {
685 updateWithDoc.
RetainAll (*onlyTheseFields);
687 updatedDoc.
AddAll (updateWithDoc);
688 if (onlyTheseFields) {
697 virtual void Remove (
const IDType&
id)
override
699#if USE_NOISY_TRACE_IN_THIS_MODULE_
700 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::MyCollectionRep_::Remove",
"id={}"_f,
id};
702 fDBRep_->WrapExecute_ ([&] () { (void)filesystem::remove (GetDocumentFilePath_ (
GUID{
id})); }, fName_,
true);
704 filesystem::path GetDocumentFilePath_ (
const GUID&
id)
const
706 return fCollectionRoot_ / (
id.As<
String> () +
".json"sv).As<filesystem::path> ();
708 optional<Document::Document> DoReadFromFS_ (
const GUID&
id)
710 using namespace IO::FileSystem;
711 filesystem::path docFilePath = GetDocumentFilePath_ (
id);
712#if USE_NOISY_TRACE_IN_THIS_MODULE_
713 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::DoReadFromFS",
"path={}"_f, docFilePath};
715 if (filesystem::exists (docFilePath)) {
716 return fDBRep_->fReader_.Read (FileInputStream::New (docFilePath)).template As<Document::Document> ();
722 filesystem::path docFilePath = GetDocumentFilePath_ (
id);
723#if USE_NOISY_TRACE_IN_THIS_MODULE_
724 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::DoWriteToFS",
"path={}"_f, docFilePath};
726 using namespace IO::FileSystem;
727 ThroughTmpFileWriter tmpFile{docFilePath};
728 IO::FileSystem::FileOutputStream::Ptr outStream = IO::FileSystem::FileOutputStream::New (tmpFile.GetFilePath ());
729 fDBRep_->fWriter_.Write (vv, outStream);
731#if qStroika_Foundation_Common_Platform_Windows
732 tmpFile.fRetryOnSharingViolationFor = fDBRep_->fRetryOnSharingViolationFor_;
739 virtual void Commit ()
override
743 virtual void Rollback ()
override
747 virtual Disposition GetDisposition ()
const override
749 return Disposition::eCompleted;
753 filesystem::path GetCollectionFilePath_ (
const String& collectionName)
const
757 return fRoot_ / (collectionName.
As<filesystem::path> ());
760 DirectoryFilesystemDatabaseRep_ () =
delete;
761 DirectoryFilesystemDatabaseRep_ (
const DirectoryFilesystemDatabaseRep_&) =
delete;
763 const Document::LocalDocumentDB::Options::DirectoryFileStorage& dfOptions)
765 , fRoot_{dfOptions.fRoot}
766 , fReader_{get<DataExchange::Variant::Reader> (dfOptions.fSerialization)}
767 , fWriter_{get<DataExchange::Variant::Writer> (dfOptions.fSerialization)}
768#if qStroika_Foundation_Common_Platform_Windows
769 , fRetryOnSharingViolationFor_{dfOptions.fRetryOnSharingViolationFor}
772 TraceContextBumper ctx{
"LocalDocumentDB::DirectoryFilesystemDatabaseRep_::DirectoryFilesystemDatabaseRep_"};
773 filesystem::create_directories (fRoot_);
774 if (dfOptions.fForceCreateNew) {
775 for (
const auto& entry : filesystem::directory_iterator{fRoot_}) {
776 filesystem::remove_all (entry.path ());
780 virtual shared_ptr<const EngineProperties> GetEngineProperties ()
const override
783 virtual String GetEngineName ()
const override
785 return "LocalDocumentDB.Folder"sv;
788 static const shared_ptr<const EngineProperties> kProps_ = Memory::MakeSharedPtr<const MyEngineProperties_> ();
791 virtual Database::Document::Connection::Options GetOptions ()
const override
795 virtual uintmax_t GetSpaceConsumed ()
const override
797 uintmax_t totalSize{};
799 for (
const auto& entry : filesystem::recursive_directory_iterator (fRoot_, filesystem::directory_options::skip_permission_denied)) {
801 if (filesystem::is_regular_file (entry.status ())) {
803 std::uintmax_t file_size = entry.file_size ();
804 totalSize += file_size;
808 catch (
const filesystem::filesystem_error& e) {
809 DbgTrace (
"suppressing error in GetSpaceConsumed () = returning zero: {}"_f, e);
817 for (
const auto& entry : filesystem::directory_iterator{fRoot_}) {
818 if (filesystem::is_directory (entry.path ())) {
819 result +=
String{entry.path ().filename ()};
826 return WrapExecute_ (
828 filesystem::create_directories (GetCollectionFilePath_ (name));
830 Debug::UncheckedDynamicPointerCast<DirectoryFilesystemDatabaseRep_> (shared_from_this ()), name)};
834 virtual void DropCollection (
const String& name)
override
836 WrapExecute_ ([&] () { filesystem::remove_all (GetCollectionFilePath_ (name)); }, name,
true);
840 Require (GetCollections ().Contains (name));
842 Debug::UncheckedDynamicPointerCast<DirectoryFilesystemDatabaseRep_> (shared_from_this ()), name)};
848 virtual void Flush ()
override
852 template <
typename FUN>
853 inline auto WrapExecute_ (FUN&& f,
const optional<String>& collectionName,
bool write) -> invoke_result_t<FUN>
855 return Document::Connection::Private_::WrapLoggingExecuteHelper_ (forward<FUN> (f),
this, fOptions_, collectionName, write);
865auto Document::LocalDocumentDB::New (
const Options& options) ->
Ptr
868 case eInternallySynchronized:
869 if (get_if<Options::MemoryStorage> (&options.fStorage)) {
870 return Ptr{Memory::MakeSharedPtr<MemoryDatabaseRep_<eInternallySynchronized>> (options)};
872 else if (
auto fop = get_if<Options::SingleFileStorage> (&options.fStorage)) {
873 return Ptr{Memory::MakeSharedPtr<SingleFileDatabaseRep_<eInternallySynchronized>> (options, *fop)};
875 else if (
auto dop = get_if<Options::DirectoryFileStorage> (&options.fStorage)) {
876 return Ptr{Memory::MakeSharedPtr<DirectoryFilesystemDatabaseRep_<eInternallySynchronized>> (options, *dop)};
880 case eNotKnownInternallySynchronized:
881 if (get_if<Options::MemoryStorage> (&options.fStorage)) {
882 return Ptr{Memory::MakeSharedPtr<MemoryDatabaseRep_<Execution::eNotKnownInternallySynchronized>> (options)};
884 else if (
auto fop = get_if<Options::SingleFileStorage> (&options.fStorage)) {
885 return Ptr{Memory::MakeSharedPtr<SingleFileDatabaseRep_<eNotKnownInternallySynchronized>> (options, *fop)};
887 else if (
auto dop = get_if<Options::DirectoryFileStorage> (&options.fStorage)) {
888 return Ptr{Memory::MakeSharedPtr<DirectoryFilesystemDatabaseRep_<eNotKnownInternallySynchronized>> (options, *dop)};
#define AssertNotImplemented()
#define RequireNotReached()
function< void(Operation op, const Ptr &documentDBConnection, const optional< String > &collectionName, const exception_ptr &e)> OpertionCallbackPtr
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual bool Add(ArgByValueType< key_type > key, ArgByValueType< mapped_type > newElt, AddReplaceMode addReplaceMode=AddReplaceMode::eAddReplaces)
nonvirtual bool ContainsKey(ArgByValueType< key_type > key) const
nonvirtual optional< mapped_type > Lookup(ArgByValueType< key_type > key) const
nonvirtual mapped_type LookupChecked(ArgByValueType< key_type > key, const THROW_IF_MISSING &throwIfMissing) const
nonvirtual unsigned int AddAll(ITERABLE_OF_ADDABLE &&items, AddReplaceMode addReplaceMode=AddReplaceMode::eAddReplaces)
nonvirtual bool RemoveIf(ArgByValueType< key_type > key)
Remove the given item, if it exists. Return true if found and removed.
nonvirtual void RemoveAll()
RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items...
nonvirtual void Remove(ArgByValueType< key_type > key)
Remove the given item (which must exist).
nonvirtual Iterable< key_type > Keys() const
nonvirtual void RetainAll(const ITERABLE_OF_KEY_TYPE &items)
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
abstract class specifying interface for readers that map a source like XML or JSON to a VariantValue ...
abstract class specifying interface for writers VariantValue objects to serialized formats like JSON,...
nonvirtual void Write(const VariantValue &v, const Streams::OutputStream::Ptr< byte > &out) const
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
nonvirtual RETURNTYPE As() const
EngineProperties captures the features associated with a given database engine (being talked to throu...
define a (simple) projection on a document, subsetting the fields of that document.
virtual Disposition GetDisposition() const =0
virtual void Rollback()=0
nonvirtual void Apply(const function< void(ArgByValueType< T > item)> &doToElement, Execution::SequencePolicy seq=Execution::SequencePolicy::eDEFAULT) const
Run the argument function (or lambda) on each element of the container.
static GUID GenerateNew() noexcept
Execution::InternallySynchronized fInternallySynchronizedLetter
use eInternallySynchronized to make letter internally synchronized