comparison Framework/Common/DatabaseManager.cpp @ 569:f18e46d7dbf8 attach-custom-data

merged find-refactoring -> attach-custom-data
author Alain Mazy <am@orthanc.team>
date Tue, 24 Sep 2024 15:04:21 +0200
parents 25cfcb752af6
children
comparison
equal deleted inserted replaced
368:82f73188b58d 569:f18e46d7dbf8
1 /** 1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store 2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium 4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium 5 * Copyright (C) 2017-2023 Osimis S.A., Belgium
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
6 * 8 *
7 * This program is free software: you can redistribute it and/or 9 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License 10 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of 11 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version. 12 * the License, or (at your option) any later version.
75 Close(); 77 Close();
76 } 78 }
77 } 79 }
78 80
79 81
80 IPrecompiledStatement* DatabaseManager::LookupCachedStatement(const StatementLocation& location) const 82 IPrecompiledStatement* DatabaseManager::LookupCachedStatement(const StatementId& statementId) const
81 { 83 {
82 CachedStatements::const_iterator found = cachedStatements_.find(location); 84 CachedStatements::const_iterator found = cachedStatements_.find(statementId);
83 85
84 if (found == cachedStatements_.end()) 86 if (found == cachedStatements_.end())
85 { 87 {
86 return NULL; 88 return NULL;
87 } 89 }
91 return found->second; 93 return found->second;
92 } 94 }
93 } 95 }
94 96
95 97
96 IPrecompiledStatement& DatabaseManager::CacheStatement(const StatementLocation& location, 98 IPrecompiledStatement& DatabaseManager::CacheStatement(const StatementId& statementId,
97 const Query& query) 99 const Query& query)
98 { 100 {
99 LOG(TRACE) << "Caching statement from " << location.GetFile() << ":" << location.GetLine(); 101 LOG(TRACE) << "Caching statement from " << statementId.GetFile() << ":" << statementId.GetLine() << "" << statementId.GetDynamicStatement();
100 102
101 std::unique_ptr<IPrecompiledStatement> statement(GetDatabase().Compile(query)); 103 std::unique_ptr<IPrecompiledStatement> statement(GetDatabase().Compile(query));
102 104
103 IPrecompiledStatement* tmp = statement.get(); 105 IPrecompiledStatement* tmp = statement.get();
104 if (tmp == NULL) 106 if (tmp == NULL)
105 { 107 {
106 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 108 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
107 } 109 }
108 110
109 assert(cachedStatements_.find(location) == cachedStatements_.end()); 111 assert(cachedStatements_.find(statementId) == cachedStatements_.end());
110 cachedStatements_[location] = statement.release(); 112 cachedStatements_[statementId] = statement.release();
111 113
112 return *tmp; 114 return *tmp;
113 } 115 }
114 116
115 117
489 { 491 {
490 case ValueType_Integer64: 492 case ValueType_Integer64:
491 return dynamic_cast<const Integer64Value&>(value).GetValue(); 493 return dynamic_cast<const Integer64Value&>(value).GetValue();
492 494
493 default: 495 default:
494 //LOG(ERROR) << value.Format(); 496 // LOG(ERROR) << value.GetType();
495 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 497 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "The returned field is not of the correct type (Integer64)");
496 } 498 }
497 } 499 }
498 } 500 }
499 501
500 502
508 { 510 {
509 int64_t value = ReadInteger64(field); 511 int64_t value = ReadInteger64(field);
510 512
511 if (value != static_cast<int64_t>(static_cast<int32_t>(value))) 513 if (value != static_cast<int64_t>(static_cast<int32_t>(value)))
512 { 514 {
513 LOG(ERROR) << "Integer overflow"; 515 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Integer overflow");
514 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
515 } 516 }
516 else 517 else
517 { 518 {
518 return static_cast<int32_t>(value); 519 return static_cast<int32_t>(value);
519 } 520 }
520 } 521 }
521 } 522 }
522 523
523 524 bool DatabaseManager::StatementBase::IsNull(size_t field) const
525 {
526 if (IsDone())
527 {
528 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
529 }
530 else
531 {
532 return GetResultField(field).GetType() == ValueType_Null;
533 }
534 }
535
524 std::string DatabaseManager::StatementBase::ReadString(size_t field) const 536 std::string DatabaseManager::StatementBase::ReadString(size_t field) const
525 { 537 {
526 const IValue& value = GetResultField(field); 538 const IValue& value = GetResultField(field);
527 539
528 switch (value.GetType()) 540 switch (value.GetType())
532 544
533 case ValueType_Utf8String: 545 case ValueType_Utf8String:
534 return dynamic_cast<const Utf8StringValue&>(value).GetContent(); 546 return dynamic_cast<const Utf8StringValue&>(value).GetContent();
535 547
536 default: 548 default:
537 //LOG(ERROR) << value.Format(); 549 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "The returned field is not of the correct type (String)");
538 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 550 }
539 } 551 }
540 } 552
541 553 std::string DatabaseManager::StatementBase::ReadStringOrNull(size_t field) const
542 554 {
543 DatabaseManager::CachedStatement::CachedStatement(const StatementLocation& location, 555 if (IsNull(field))
556 {
557 return std::string();
558 }
559 else
560 {
561 return ReadString(field);
562 }
563 }
564
565 DatabaseManager::CachedStatement::CachedStatement(const StatementId& statementId,
544 DatabaseManager& manager, 566 DatabaseManager& manager,
545 const std::string& sql) : 567 const std::string& sql) :
546 StatementBase(manager), 568 StatementBase(manager),
547 location_(location) 569 statementId_(statementId)
548 { 570 {
549 statement_ = GetManager().LookupCachedStatement(location_); 571 statement_ = GetManager().LookupCachedStatement(statementId_);
550 572
551 if (statement_ == NULL) 573 if (statement_ == NULL)
552 { 574 {
553 SetQuery(new Query(sql)); 575 SetQuery(new Query(sql));
554 } 576 }
555 else 577 else
556 { 578 {
557 LOG(TRACE) << "Reusing cached statement from " 579 LOG(TRACE) << "Reusing cached statement from "
558 << location_.GetFile() << ":" << location_.GetLine(); 580 << statementId_.GetFile() << ":" << statementId_.GetLine() << " " << statementId_.GetDynamicStatement();
559 } 581 }
560 } 582 }
561 583
562 584 void DatabaseManager::CachedStatement::ExecuteInternal(const Dictionary& parameters, bool withResults)
563 void DatabaseManager::CachedStatement::Execute(const Dictionary& parameters)
564 { 585 {
565 try 586 try
566 { 587 {
567 std::unique_ptr<Query> query(ReleaseQuery()); 588 std::unique_ptr<Query> query(ReleaseQuery());
568 589
569 if (query.get() != NULL) 590 if (query.get() != NULL)
570 { 591 {
571 // Register the newly-created statement 592 // Register the newly-created statement
572 assert(statement_ == NULL); 593 assert(statement_ == NULL);
573 statement_ = &GetManager().CacheStatement(location_, *query); 594 statement_ = &GetManager().CacheStatement(statementId_, *query);
574 } 595 }
575 596
576 assert(statement_ != NULL); 597 assert(statement_ != NULL);
577 598
578 /* 599 /*
584 boost::lexical_cast<std::string>(location_.GetLine())); 605 boost::lexical_cast<std::string>(location_.GetLine()));
585 OrthancPlugins::MetricsTimer timer(name.c_str()); 606 OrthancPlugins::MetricsTimer timer(name.c_str());
586 #endif 607 #endif
587 */ 608 */
588 609
589 SetResult(GetTransaction().Execute(*statement_, parameters)); 610 if (withResults)
611 {
612 SetResult(GetTransaction().Execute(*statement_, parameters));
613 }
614 else
615 {
616 GetTransaction().ExecuteWithoutResult(*statement_, parameters);
617 }
590 } 618 }
591 catch (Orthanc::OrthancException& e) 619 catch (Orthanc::OrthancException& e)
592 { 620 {
593 GetManager().CloseIfUnavailable(e.GetErrorCode()); 621 GetManager().CloseIfUnavailable(e.GetErrorCode());
594 throw; 622 throw;
595 } 623 }
596 } 624 }
597 625
626
627 void DatabaseManager::CachedStatement::Execute(const Dictionary& parameters)
628 {
629 ExecuteInternal(parameters, true);
630 }
631
632 void DatabaseManager::CachedStatement::ExecuteWithoutResult(const Dictionary& parameters)
633 {
634 ExecuteInternal(parameters, false);
635 }
636
598 637
599 DatabaseManager::StandaloneStatement::StandaloneStatement(DatabaseManager& manager, 638 DatabaseManager::StandaloneStatement::StandaloneStatement(DatabaseManager& manager,
600 const std::string& sql) : 639 const std::string& sql) :
601 StatementBase(manager) 640 StatementBase(manager)
602 { 641 {
611 statement_.reset(); 650 statement_.reset();
612 } 651 }
613 652
614 653
615 void DatabaseManager::StandaloneStatement::Execute(const Dictionary& parameters) 654 void DatabaseManager::StandaloneStatement::Execute(const Dictionary& parameters)
655 {
656 ExecuteInternal(parameters, true);
657 }
658
659 void DatabaseManager::StandaloneStatement::ExecuteWithoutResult(const Dictionary& parameters)
660 {
661 ExecuteInternal(parameters, false);
662 }
663
664 void DatabaseManager::StandaloneStatement::ExecuteInternal(const Dictionary& parameters, bool withResults)
616 { 665 {
617 try 666 try
618 { 667 {
619 std::unique_ptr<Query> query(ReleaseQuery()); 668 std::unique_ptr<Query> query(ReleaseQuery());
620 assert(query.get() != NULL); 669 assert(query.get() != NULL);
623 // is not destroyed, as the "IResult" can make calls to the 672 // is not destroyed, as the "IResult" can make calls to the
624 // statement (this is the case for SQLite and MySQL) - (*) 673 // statement (this is the case for SQLite and MySQL) - (*)
625 statement_.reset(GetManager().GetDatabase().Compile(*query)); 674 statement_.reset(GetManager().GetDatabase().Compile(*query));
626 assert(statement_.get() != NULL); 675 assert(statement_.get() != NULL);
627 676
628 SetResult(GetTransaction().Execute(*statement_, parameters)); 677 std::unique_ptr<IResult> result(GetTransaction().Execute(*statement_, parameters));
678
679 if (withResults)
680 {
681 SetResult(result.release());
682 }
629 } 683 }
630 catch (Orthanc::OrthancException& e) 684 catch (Orthanc::OrthancException& e)
631 { 685 {
632 GetManager().CloseIfUnavailable(e.GetErrorCode()); 686 GetManager().CloseIfUnavailable(e.GetErrorCode());
633 throw; 687 throw;