comparison Framework/Plugins/IndexBackend.cpp @ 533:2d3163d992fd find-refactoring

merged large-queries -> find-refactoring
author Alain Mazy <am@orthanc.team>
date Fri, 06 Sep 2024 15:32:06 +0200
parents 25cfcb752af6
children 4ecf50a4521c
comparison
equal deleted inserted replaced
527:61338585e7f7 533:2d3163d992fd
115 void IndexBackend::ReadChangesInternal(IDatabaseBackendOutput& output, 115 void IndexBackend::ReadChangesInternal(IDatabaseBackendOutput& output,
116 bool& done, 116 bool& done,
117 DatabaseManager& manager, 117 DatabaseManager& manager,
118 DatabaseManager::CachedStatement& statement, 118 DatabaseManager::CachedStatement& statement,
119 const Dictionary& args, 119 const Dictionary& args,
120 uint32_t limit) 120 uint32_t limit,
121 { 121 bool returnFirstResults)
122 {
123 struct Change
124 {
125 int64_t seq_;
126 int32_t changeType_;
127 OrthancPluginResourceType resourceType_;
128 std::string publicId_;
129 std::string changeDate_;
130
131 Change(int64_t seq, int32_t changeType, OrthancPluginResourceType resourceType, const std::string& publicId, const std::string& changeDate)
132 : seq_(seq), changeType_(changeType), resourceType_(resourceType), publicId_(publicId), changeDate_(changeDate)
133 {
134 }
135 };
136
122 statement.Execute(args); 137 statement.Execute(args);
123 138
124 uint32_t count = 0; 139 std::list<Change> changes;
125 140 while (!statement.IsDone())
126 while (count < limit && 141 {
127 !statement.IsDone()) 142 changes.push_back(Change(
128 {
129 output.AnswerChange(
130 statement.ReadInteger64(0), 143 statement.ReadInteger64(0),
131 statement.ReadInteger32(1), 144 statement.ReadInteger32(1),
132 static_cast<OrthancPluginResourceType>(statement.ReadInteger32(2)), 145 static_cast<OrthancPluginResourceType>(statement.ReadInteger32(2)),
133 statement.ReadString(3), 146 statement.ReadString(3),
134 statement.ReadString(4)); 147 statement.ReadString(4)
148 ));
135 149
136 statement.Next(); 150 statement.Next();
137 count++; 151 }
138 } 152
139 153 done = changes.size() <= limit; // 'done' means we have returned all requested changes
140 done = (count < limit || 154
141 statement.IsDone()); 155 // if we have retrieved more changes than requested -> cleanup
156 if (changes.size() > limit)
157 {
158 assert(changes.size() == limit+1); // the statement should only request 1 element more
159
160 if (returnFirstResults)
161 {
162 changes.pop_back();
163 }
164 else
165 {
166 changes.pop_front();
167 }
168 }
169
170 for (std::list<Change>::const_iterator it = changes.begin(); it != changes.end(); ++it)
171 {
172 output.AnswerChange(it->seq_, it->changeType_, it->resourceType_, it->publicId_, it->changeDate_);
173 }
142 } 174 }
143 175
144 176
145 void IndexBackend::ReadExportedResourcesInternal(IDatabaseBackendOutput& output, 177 void IndexBackend::ReadExportedResourcesInternal(IDatabaseBackendOutput& output,
146 bool& done, 178 bool& done,
552 args.SetIntegerValue("since", since); 584 args.SetIntegerValue("since", since);
553 585
554 ReadListOfStrings(target, statement, args); 586 ReadListOfStrings(target, statement, args);
555 } 587 }
556 588
557
558 /* Use GetOutput().AnswerChange() */
559 void IndexBackend::GetChanges(IDatabaseBackendOutput& output, 589 void IndexBackend::GetChanges(IDatabaseBackendOutput& output,
560 bool& done /*out*/, 590 bool& done /*out*/,
561 DatabaseManager& manager, 591 DatabaseManager& manager,
562 int64_t since, 592 int64_t since,
563 uint32_t limit) 593 uint32_t limit)
564 { 594 {
565 std::string suffix; 595 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 5)
596 GetChangesExtended(output, done, manager, since, -1, _OrthancPluginChangeType_All, limit);
597 #else
598 GetChangesExtended(output, done, manager, since, -1, 65535, limit);
599 #endif
600 }
601
602 /* Use GetOutput().AnswerChange() */
603 void IndexBackend::GetChangesExtended(IDatabaseBackendOutput& output,
604 bool& done /*out*/,
605 DatabaseManager& manager,
606 int64_t since,
607 int64_t to,
608 int32_t changeType,
609 uint32_t limit)
610 {
611 std::string limitSuffix;
566 if (manager.GetDialect() == Dialect_MSSQL) 612 if (manager.GetDialect() == Dialect_MSSQL)
567 { 613 {
568 suffix = "OFFSET 0 ROWS FETCH FIRST ${limit} ROWS ONLY"; 614 limitSuffix = "OFFSET 0 ROWS FETCH FIRST ${limit} ROWS ONLY";
569 } 615 }
570 else 616 else
571 { 617 {
572 suffix = "LIMIT ${limit}"; 618 limitSuffix = "LIMIT ${limit}";
573 } 619 }
574 620
575 DatabaseManager::CachedStatement statement( 621 std::vector<std::string> filters;
576 STATEMENT_FROM_HERE, manager, 622 bool hasSince = false;
577 "SELECT Changes.seq, Changes.changeType, Changes.resourceType, Resources.publicId, " 623 bool hasTo = false;
578 "Changes.date FROM Changes INNER JOIN Resources " 624 bool hasFilterType = false;
579 "ON Changes.internalId = Resources.internalId WHERE seq>${since} ORDER BY seq " + suffix); 625
580 626 if (since > 0)
627 {
628 hasSince = true;
629 filters.push_back("seq>${since}");
630 }
631 if (to != -1)
632 {
633 hasTo = true;
634 filters.push_back("seq<=${to}");
635 }
636 if (changeType != _OrthancPluginChangeType_All)
637 {
638 hasFilterType = true;
639 filters.push_back("changeType=${changeType}");
640 }
641
642 std::string filtersString;
643 if (filters.size() > 0)
644 {
645 Orthanc::Toolbox::JoinStrings(filtersString, filters, " AND ");
646 filtersString = "WHERE " + filtersString;
647 }
648
649 std::string sql;
650 bool returnFirstResults;
651 if (hasTo && !hasSince)
652 {
653 // in this case, we want the largest values but we want them ordered in ascending order
654 sql = "SELECT * FROM (SELECT Changes.seq, Changes.changeType, Changes.resourceType, Resources.publicId, Changes.date "
655 "FROM Changes INNER JOIN Resources "
656 "ON Changes.internalId = Resources.internalId " + filtersString + " ORDER BY seq DESC " + limitSuffix +
657 ") AS FilteredChanges ORDER BY seq ASC";
658
659 returnFirstResults = false;
660 }
661 else
662 {
663 // default query: we want the smallest values ordered in ascending order
664 sql = "SELECT Changes.seq, Changes.changeType, Changes.resourceType, Resources.publicId, "
665 "Changes.date FROM Changes INNER JOIN Resources "
666 "ON Changes.internalId = Resources.internalId " + filtersString + " ORDER BY seq ASC " + limitSuffix;
667 returnFirstResults = true;
668 }
669
670 DatabaseManager::CachedStatement statement(STATEMENT_FROM_HERE_DYNAMIC(sql), manager, sql);
581 statement.SetReadOnly(true); 671 statement.SetReadOnly(true);
672 Dictionary args;
673
582 statement.SetParameterType("limit", ValueType_Integer64); 674 statement.SetParameterType("limit", ValueType_Integer64);
583 statement.SetParameterType("since", ValueType_Integer64); 675 args.SetIntegerValue("limit", limit + 1); // we take limit+1 because we use the +1 to know if "Done" must be set to true
584 676
585 Dictionary args; 677 if (hasSince)
586 args.SetIntegerValue("limit", limit + 1); 678 {
587 args.SetIntegerValue("since", since); 679 statement.SetParameterType("since", ValueType_Integer64);
588 680 args.SetIntegerValue("since", since);
589 ReadChangesInternal(output, done, manager, statement, args, limit); 681 }
682
683 if (hasTo)
684 {
685 statement.SetParameterType("to", ValueType_Integer64);
686 args.SetIntegerValue("to", to);
687 }
688
689 if (hasFilterType)
690 {
691 statement.SetParameterType("changeType", ValueType_Integer64);
692 args.SetIntegerValue("changeType", changeType);
693 }
694
695 ReadChangesInternal(output, done, manager, statement, args, limit, returnFirstResults);
590 } 696 }
591 697
592 698
593 void IndexBackend::GetChildrenInternalId(std::list<int64_t>& target /*out*/, 699 void IndexBackend::GetChildrenInternalId(std::list<int64_t>& target /*out*/,
594 DatabaseManager& manager, 700 DatabaseManager& manager,
684 statement.SetReadOnly(true); 790 statement.SetReadOnly(true);
685 791
686 Dictionary args; 792 Dictionary args;
687 793
688 bool done; // Ignored 794 bool done; // Ignored
689 ReadChangesInternal(output, done, manager, statement, args, 1); 795 ReadChangesInternal(output, done, manager, statement, args, 1, true);
690 } 796 }
691 797
692 798
693 /* Use GetOutput().AnswerExportedResource() */ 799 /* Use GetOutput().AnswerExportedResource() */
694 void IndexBackend::GetLastExportedResource(IDatabaseBackendOutput& output, 800 void IndexBackend::GetLastExportedResource(IDatabaseBackendOutput& output,