comparison OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp @ 4589:bec74e29f86b db-changes

attaching the listener to transactions in IDatabaseWrapper
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 12 Mar 2021 15:33:47 +0100
parents 9224e107d613
children ff8170d17d90
comparison
equal deleted inserted replaced
4588:94147ce2f097 4589:bec74e29f86b
45 #include <stdio.h> 45 #include <stdio.h>
46 #include <boost/lexical_cast.hpp> 46 #include <boost/lexical_cast.hpp>
47 47
48 namespace Orthanc 48 namespace Orthanc
49 { 49 {
50 namespace Internals 50 class SQLiteDatabaseWrapper::SignalFileDeleted : public SQLite::IScalarFunction
51 { 51 {
52 class SignalFileDeleted : public SQLite::IScalarFunction 52 private:
53 { 53 SQLiteDatabaseWrapper& sqlite_;
54 private: 54
55 IDatabaseListener& listener_; 55 public:
56 56 SignalFileDeleted(SQLiteDatabaseWrapper& sqlite) :
57 public: 57 sqlite_(sqlite)
58 SignalFileDeleted(IDatabaseListener& listener) : 58 {
59 listener_(listener) 59 }
60 { 60
61 } 61 virtual const char* GetName() const ORTHANC_OVERRIDE
62 62 {
63 virtual const char* GetName() const ORTHANC_OVERRIDE 63 return "SignalFileDeleted";
64 { 64 }
65 return "SignalFileDeleted"; 65
66 } 66 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE
67 67 {
68 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE 68 return 7;
69 { 69 }
70 return 7; 70
71 } 71 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE
72 72 {
73 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE 73 if (sqlite_.listener_ != NULL)
74 { 74 {
75 std::string uncompressedMD5, compressedMD5; 75 std::string uncompressedMD5, compressedMD5;
76 76
77 if (!context.IsNullValue(5)) 77 if (!context.IsNullValue(5))
78 { 78 {
89 static_cast<uint64_t>(context.GetInt64Value(2)), 89 static_cast<uint64_t>(context.GetInt64Value(2)),
90 uncompressedMD5, 90 uncompressedMD5,
91 static_cast<CompressionType>(context.GetIntValue(3)), 91 static_cast<CompressionType>(context.GetIntValue(3)),
92 static_cast<uint64_t>(context.GetInt64Value(4)), 92 static_cast<uint64_t>(context.GetInt64Value(4)),
93 compressedMD5); 93 compressedMD5);
94 94
95 listener_.SignalAttachmentDeleted(info); 95 sqlite_.listener_->SignalAttachmentDeleted(info);
96 } 96 }
97 }; 97 }
98 98 };
99 class SignalResourceDeleted : public SQLite::IScalarFunction 99
100 { 100
101 private: 101 class SQLiteDatabaseWrapper::SignalResourceDeleted : public SQLite::IScalarFunction
102 IDatabaseListener& listener_; 102 {
103 103 private:
104 public: 104 SQLiteDatabaseWrapper& sqlite_;
105 SignalResourceDeleted(IDatabaseListener& listener) : 105
106 listener_(listener) 106 public:
107 { 107 SignalResourceDeleted(SQLiteDatabaseWrapper& sqlite) :
108 } 108 sqlite_(sqlite)
109 109 {
110 virtual const char* GetName() const ORTHANC_OVERRIDE 110 }
111 { 111
112 return "SignalResourceDeleted"; 112 virtual const char* GetName() const ORTHANC_OVERRIDE
113 } 113 {
114 114 return "SignalResourceDeleted";
115 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE 115 }
116 { 116
117 return 2; 117 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE
118 } 118 {
119 119 return 2;
120 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE 120 }
121 { 121
122 listener_.SignalResourceDeleted(static_cast<ResourceType>(context.GetIntValue(1)), 122 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE
123 context.GetStringValue(0)); 123 {
124 } 124 if (sqlite_.listener_ != NULL)
125 }; 125 {
126 126 sqlite_.listener_->SignalResourceDeleted(static_cast<ResourceType>(context.GetIntValue(1)),
127 class SignalRemainingAncestor : public SQLite::IScalarFunction 127 context.GetStringValue(0));
128 { 128 }
129 private: 129 }
130 bool hasRemainingAncestor_; 130 };
131 std::string remainingPublicId_; 131
132 ResourceType remainingType_; 132
133 133 class SQLiteDatabaseWrapper::SignalRemainingAncestor : public SQLite::IScalarFunction
134 public: 134 {
135 SignalRemainingAncestor() : 135 private:
136 hasRemainingAncestor_(false) 136 bool hasRemainingAncestor_;
137 { 137 std::string remainingPublicId_;
138 } 138 ResourceType remainingType_;
139 139
140 void Reset() 140 public:
141 { 141 SignalRemainingAncestor() :
142 hasRemainingAncestor_ = false; 142 hasRemainingAncestor_(false)
143 } 143 {
144 144 }
145 virtual const char* GetName() const ORTHANC_OVERRIDE 145
146 { 146 void Reset()
147 return "SignalRemainingAncestor"; 147 {
148 } 148 hasRemainingAncestor_ = false;
149 149 }
150 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE 150
151 { 151 virtual const char* GetName() const ORTHANC_OVERRIDE
152 return 2; 152 {
153 } 153 return "SignalRemainingAncestor";
154 154 }
155 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE 155
156 { 156 virtual unsigned int GetCardinality() const ORTHANC_OVERRIDE
157 CLOG(TRACE, SQLITE) << "There exists a remaining ancestor with public ID \"" 157 {
158 << context.GetStringValue(0) << "\" of type " 158 return 2;
159 << context.GetIntValue(1); 159 }
160 160
161 if (!hasRemainingAncestor_ || 161 virtual void Compute(SQLite::FunctionContext& context) ORTHANC_OVERRIDE
162 remainingType_ >= context.GetIntValue(1)) 162 {
163 { 163 CLOG(TRACE, SQLITE) << "There exists a remaining ancestor with public ID \""
164 hasRemainingAncestor_ = true; 164 << context.GetStringValue(0) << "\" of type "
165 remainingPublicId_ = context.GetStringValue(0); 165 << context.GetIntValue(1);
166 remainingType_ = static_cast<ResourceType>(context.GetIntValue(1)); 166
167 } 167 if (!hasRemainingAncestor_ ||
168 } 168 remainingType_ >= context.GetIntValue(1))
169 169 {
170 bool HasRemainingAncestor() const 170 hasRemainingAncestor_ = true;
171 { 171 remainingPublicId_ = context.GetStringValue(0);
172 return hasRemainingAncestor_; 172 remainingType_ = static_cast<ResourceType>(context.GetIntValue(1));
173 } 173 }
174 174 }
175 const std::string& GetRemainingAncestorId() const 175
176 { 176 bool HasRemainingAncestor() const
177 assert(hasRemainingAncestor_); 177 {
178 return remainingPublicId_; 178 return hasRemainingAncestor_;
179 } 179 }
180 180
181 ResourceType GetRemainingAncestorType() const 181 const std::string& GetRemainingAncestorId() const
182 { 182 {
183 assert(hasRemainingAncestor_); 183 assert(hasRemainingAncestor_);
184 return remainingType_; 184 return remainingPublicId_;
185 } 185 }
186 }; 186
187 } 187 ResourceType GetRemainingAncestorType() const
188 {
189 assert(hasRemainingAncestor_);
190 return remainingType_;
191 }
192 };
188 193
189 194
190 void SQLiteDatabaseWrapper::GetChangesInternal(std::list<ServerIndexChange>& target, 195 void SQLiteDatabaseWrapper::GetChangesInternal(std::list<ServerIndexChange>& target,
191 bool& done, 196 bool& done,
192 SQLite::Statement& s, 197 SQLite::Statement& s,
434 } 439 }
435 440
436 t.Commit(); 441 t.Commit();
437 } 442 }
438 443
439 signalRemainingAncestor_ = new Internals::SignalRemainingAncestor; 444 signalRemainingAncestor_ = dynamic_cast<SignalRemainingAncestor*>(db_.Register(new SignalRemainingAncestor));
440 db_.Register(signalRemainingAncestor_); 445 db_.Register(new SignalFileDeleted(*this));
446 db_.Register(new SignalResourceDeleted(*this));
441 } 447 }
442 448
443 449
444 static void ExecuteUpgradeScript(SQLite::Connection& db, 450 static void ExecuteUpgradeScript(SQLite::Connection& db,
445 ServerResources::FileResourceId script) 451 ServerResources::FileResourceId script)
501 version_ = 6; 507 version_ = 6;
502 } 508 }
503 } 509 }
504 510
505 511
506 void SQLiteDatabaseWrapper::SetListener(IDatabaseListener& listener)
507 {
508 listener_ = &listener;
509 db_.Register(new Internals::SignalFileDeleted(listener));
510 db_.Register(new Internals::SignalResourceDeleted(listener));
511 }
512
513
514 void SQLiteDatabaseWrapper::ClearTable(const std::string& tableName) 512 void SQLiteDatabaseWrapper::ClearTable(const std::string& tableName)
515 { 513 {
516 db_.Execute("DELETE FROM " + tableName); 514 db_.Execute("DELETE FROM " + tableName);
517 } 515 }
518 516
601 SQLiteDatabaseWrapper& that_; 599 SQLiteDatabaseWrapper& that_;
602 std::unique_ptr<SQLite::Transaction> transaction_; 600 std::unique_ptr<SQLite::Transaction> transaction_;
603 int64_t initialDiskSize_; 601 int64_t initialDiskSize_;
604 602
605 public: 603 public:
606 ReadWriteTransaction(SQLiteDatabaseWrapper& that) : 604 ReadWriteTransaction(SQLiteDatabaseWrapper& that,
605 IDatabaseListener& listener) :
607 that_(that), 606 that_(that),
608 transaction_(new SQLite::Transaction(that_.db_)) 607 transaction_(new SQLite::Transaction(that_.db_))
609 { 608 {
609 assert(that_.listener_ == NULL);
610 that_.listener_ = &listener; // TODO - STORE IN TRANSACTION
611
610 #if defined(NDEBUG) 612 #if defined(NDEBUG)
611 // Release mode 613 // Release mode
612 initialDiskSize_ = 0; 614 initialDiskSize_ = 0;
613 #else 615 #else
614 // Debug mode 616 // Debug mode
615 initialDiskSize_ = static_cast<int64_t>(that_.GetTotalCompressedSize()); 617 initialDiskSize_ = static_cast<int64_t>(that_.GetTotalCompressedSize());
616 #endif 618 #endif
617 } 619 }
618 620
621 virtual ~ReadWriteTransaction()
622 {
623 assert(that_.listener_ != NULL);
624 that_.listener_ = NULL; // TODO - STORE IN TRANSACTION
625 }
626
619 void Begin() 627 void Begin()
620 { 628 {
621 transaction_->Begin(); 629 transaction_->Begin();
622 } 630 }
623 631
636 }; 644 };
637 645
638 646
639 class SQLiteDatabaseWrapper::ReadOnlyTransaction : public IDatabaseWrapper::ITransaction 647 class SQLiteDatabaseWrapper::ReadOnlyTransaction : public IDatabaseWrapper::ITransaction
640 { 648 {
649 private:
650 SQLiteDatabaseWrapper& that_;
651
641 public: 652 public:
653 ReadOnlyTransaction(SQLiteDatabaseWrapper& that,
654 IDatabaseListener& listener) :
655 that_(that)
656 {
657 assert(that_.listener_ == NULL);
658 that_.listener_ = &listener;
659 }
660
661 virtual ~ReadOnlyTransaction()
662 {
663 assert(that_.listener_ != NULL);
664 that_.listener_ = NULL;
665 }
666
642 virtual void Rollback() ORTHANC_OVERRIDE 667 virtual void Rollback() ORTHANC_OVERRIDE
643 { 668 {
644 } 669 }
645 670
646 virtual void Commit(int64_t fileSizeDelta /* only used in debug */) ORTHANC_OVERRIDE 671 virtual void Commit(int64_t fileSizeDelta /* only used in debug */) ORTHANC_OVERRIDE
651 } 676 }
652 } 677 }
653 }; 678 };
654 679
655 680
656 IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction(TransactionType type) 681 IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction(TransactionType type,
682 IDatabaseListener& listener)
657 { 683 {
658 switch (type) 684 switch (type)
659 { 685 {
660 case TransactionType_ReadOnly: 686 case TransactionType_ReadOnly:
661 return new ReadOnlyTransaction; // This is a no-op transaction in SQLite (thanks to mutex) 687 return new ReadOnlyTransaction(*this, listener); // This is a no-op transaction in SQLite (thanks to mutex)
662 688
663 case TransactionType_ReadWrite: 689 case TransactionType_ReadWrite:
664 { 690 {
665 std::unique_ptr<ReadWriteTransaction> transaction; 691 std::unique_ptr<ReadWriteTransaction> transaction;
666 transaction.reset(new ReadWriteTransaction(*this)); 692 transaction.reset(new ReadWriteTransaction(*this, listener));
667 transaction->Begin(); 693 transaction->Begin();
668 return transaction.release(); 694 return transaction.release();
669 } 695 }
670 696
671 default: 697 default: