PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
index_database.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
22#pragma once
23
24#include "audit_record.h"
25#include "instance_record.h"
26#include "migration_runner.h"
27#include "mpps_record.h"
28#include "patient_record.h"
29#include "series_record.h"
30#include "study_record.h"
31#include "ups_workitem.h"
32#include "worklist_record.h"
33
34#include <kcenon/common/patterns/result.h>
35
36#include <chrono>
37#include <filesystem>
38#include <memory>
39#include <optional>
40#include <string>
41#include <string_view>
42#include <vector>
43
44#ifdef PACS_WITH_DATABASE_SYSTEM
46#endif
47
48// Forward declaration of SQLite handle
49struct sqlite3;
50
51namespace kcenon::pacs::storage {
52
53class patient_repository;
54class study_repository;
55class series_repository;
56class instance_repository;
57class mpps_repository;
58class worklist_repository;
59class ups_repository;
60class audit_repository;
61
70 size_t cache_size_mb = 64;
71
73 bool wal_mode = true;
74
76 bool mmap_enabled = true;
77
79 size_t mmap_size = 1024 * 1024 * 1024;
80};
81
83template <typename T>
85
87using VoidResult = kcenon::common::VoidResult;
88
124public:
135 [[nodiscard]] static auto open(std::string_view db_path)
137
153 [[nodiscard]] static auto open(std::string_view db_path,
154 const index_config& config)
156
161
162 // Non-copyable, movable
164 auto operator=(const index_database&) -> index_database& = delete;
165 index_database(index_database&&) noexcept;
166 auto operator=(index_database&&) noexcept -> index_database&;
167
168 // ========================================================================
169 // Patient Operations
170 // ========================================================================
171
184 [[nodiscard]] auto upsert_patient(std::string_view patient_id,
185 std::string_view patient_name = "",
186 std::string_view birth_date = "",
187 std::string_view sex = "")
188 -> Result<int64_t>;
189
196 [[nodiscard]] auto upsert_patient(const patient_record& record)
197 -> Result<int64_t>;
198
205 [[nodiscard]] auto find_patient(std::string_view patient_id) const
206 -> std::optional<patient_record>;
207
214 [[nodiscard]] auto find_patient_by_pk(int64_t pk) const
215 -> std::optional<patient_record>;
216
228 [[nodiscard]] auto search_patients(const patient_query& query) const
229 -> Result<std::vector<patient_record>>;
230
240 [[nodiscard]] auto delete_patient(std::string_view patient_id)
241 -> VoidResult;
242
248 [[nodiscard]] auto patient_count() const -> Result<size_t>;
249
250 // ========================================================================
251 // Study Operations
252 // ========================================================================
253
270 [[nodiscard]] auto upsert_study(int64_t patient_pk,
271 std::string_view study_uid,
272 std::string_view study_id = "",
273 std::string_view study_date = "",
274 std::string_view study_time = "",
275 std::string_view accession_number = "",
276 std::string_view referring_physician = "",
277 std::string_view study_description = "")
278 -> Result<int64_t>;
279
286 [[nodiscard]] auto upsert_study(const study_record& record)
287 -> Result<int64_t>;
288
295 [[nodiscard]] auto find_study(std::string_view study_uid) const
296 -> std::optional<study_record>;
297
304 [[nodiscard]] auto find_study_by_pk(int64_t pk) const
305 -> std::optional<study_record>;
306
313 [[nodiscard]] auto list_studies(std::string_view patient_id) const
314 -> Result<std::vector<study_record>>;
315
325 [[nodiscard]] auto search_studies(const study_query& query) const
326 -> Result<std::vector<study_record>>;
327
336 [[nodiscard]] auto delete_study(std::string_view study_uid) -> VoidResult;
337
343 [[nodiscard]] auto study_count() const -> Result<size_t>;
344
351 [[nodiscard]] auto study_count(std::string_view patient_id) const -> Result<size_t>;
352
361 [[nodiscard]] auto update_modalities_in_study(int64_t study_pk)
362 -> VoidResult;
363
364 // ========================================================================
365 // Series Operations
366 // ========================================================================
367
383 [[nodiscard]] auto upsert_series(int64_t study_pk,
384 std::string_view series_uid,
385 std::string_view modality = "",
386 std::optional<int> series_number = std::nullopt,
387 std::string_view series_description = "",
388 std::string_view body_part_examined = "",
389 std::string_view station_name = "")
390 -> Result<int64_t>;
391
398 [[nodiscard]] auto upsert_series(const series_record& record)
399 -> Result<int64_t>;
400
407 [[nodiscard]] auto find_series(std::string_view series_uid) const
408 -> std::optional<series_record>;
409
416 [[nodiscard]] auto find_series_by_pk(int64_t pk) const
417 -> std::optional<series_record>;
418
425 [[nodiscard]] auto list_series(std::string_view study_uid) const
426 -> Result<std::vector<series_record>>;
427
437 [[nodiscard]] auto search_series(const series_query& query) const
438 -> Result<std::vector<series_record>>;
439
448 [[nodiscard]] auto delete_series(std::string_view series_uid) -> VoidResult;
449
455 [[nodiscard]] auto series_count() const -> Result<size_t>;
456
463 [[nodiscard]] auto series_count(std::string_view study_uid) const -> Result<size_t>;
464
465 // ========================================================================
466 // Instance Operations
467 // ========================================================================
468
484 [[nodiscard]] auto upsert_instance(int64_t series_pk,
485 std::string_view sop_uid,
486 std::string_view sop_class_uid,
487 std::string_view file_path,
488 int64_t file_size,
489 std::string_view transfer_syntax = "",
490 std::optional<int> instance_number = std::nullopt)
491 -> Result<int64_t>;
492
499 [[nodiscard]] auto upsert_instance(const instance_record& record)
500 -> Result<int64_t>;
501
508 [[nodiscard]] auto find_instance(std::string_view sop_uid) const
509 -> std::optional<instance_record>;
510
517 [[nodiscard]] auto find_instance_by_pk(int64_t pk) const
518 -> std::optional<instance_record>;
519
526 [[nodiscard]] auto list_instances(std::string_view series_uid) const
527 -> Result<std::vector<instance_record>>;
528
537 [[nodiscard]] auto search_instances(const instance_query& query) const
538 -> Result<std::vector<instance_record>>;
539
546 [[nodiscard]] auto delete_instance(std::string_view sop_uid) -> VoidResult;
547
553 [[nodiscard]] auto instance_count() const -> Result<size_t>;
554
561 [[nodiscard]] auto instance_count(std::string_view series_uid) const -> Result<size_t>;
562
563 // ========================================================================
564 // MPPS Operations
565 // ========================================================================
566
581 [[nodiscard]] auto create_mpps(std::string_view mpps_uid,
582 std::string_view station_ae = "",
583 std::string_view modality = "",
584 std::string_view study_uid = "",
585 std::string_view accession_no = "",
586 std::string_view start_datetime = "")
587 -> Result<int64_t>;
588
595 [[nodiscard]] auto create_mpps(const mpps_record& record) -> Result<int64_t>;
596
611 [[nodiscard]] auto update_mpps(std::string_view mpps_uid,
612 std::string_view new_status,
613 std::string_view end_datetime = "",
614 std::string_view performed_series = "")
615 -> VoidResult;
616
625 [[nodiscard]] auto update_mpps(const mpps_record& record) -> VoidResult;
626
633 [[nodiscard]] auto find_mpps(std::string_view mpps_uid) const
634 -> std::optional<mpps_record>;
635
642 [[nodiscard]] auto find_mpps_by_pk(int64_t pk) const
643 -> std::optional<mpps_record>;
644
651 [[nodiscard]] auto list_active_mpps(std::string_view station_ae) const
652 -> Result<std::vector<mpps_record>>;
653
660 [[nodiscard]] auto find_mpps_by_study(std::string_view study_uid) const
661 -> Result<std::vector<mpps_record>>;
662
669 [[nodiscard]] auto search_mpps(const mpps_query& query) const
670 -> Result<std::vector<mpps_record>>;
671
678 [[nodiscard]] auto delete_mpps(std::string_view mpps_uid) -> VoidResult;
679
685 [[nodiscard]] auto mpps_count() const -> Result<size_t>;
686
693 [[nodiscard]] auto mpps_count(std::string_view status) const -> Result<size_t>;
694
695 // ========================================================================
696 // Worklist Operations
697 // ========================================================================
698
708 [[nodiscard]] auto add_worklist_item(const worklist_item& item)
709 -> Result<int64_t>;
710
722 [[nodiscard]] auto update_worklist_status(std::string_view step_id,
723 std::string_view accession_no,
724 std::string_view new_status)
725 -> VoidResult;
726
737 [[nodiscard]] auto query_worklist(const worklist_query& query) const
738 -> Result<std::vector<worklist_item>>;
739
747 [[nodiscard]] auto find_worklist_item(std::string_view step_id,
748 std::string_view accession_no) const
749 -> std::optional<worklist_item>;
750
757 [[nodiscard]] auto find_worklist_by_pk(int64_t pk) const
758 -> std::optional<worklist_item>;
759
767 [[nodiscard]] auto delete_worklist_item(std::string_view step_id,
768 std::string_view accession_no)
769 -> VoidResult;
770
780 [[nodiscard]] auto cleanup_old_worklist_items(std::chrono::hours age)
781 -> Result<size_t>;
782
805 [[nodiscard]] auto cleanup_worklist_items_before(
806 std::chrono::system_clock::time_point before) -> Result<size_t>;
807
813 [[nodiscard]] auto worklist_count() const -> Result<size_t>;
814
821 [[nodiscard]] auto worklist_count(std::string_view status) const -> Result<size_t>;
822
823 // ========================================================================
824 // UPS Workitem Operations
825 // ========================================================================
826
836 [[nodiscard]] auto create_ups_workitem(const ups_workitem& workitem)
837 -> Result<int64_t>;
838
850 [[nodiscard]] auto update_ups_workitem(const ups_workitem& workitem)
851 -> VoidResult;
852
863 [[nodiscard]] auto change_ups_state(std::string_view workitem_uid,
864 std::string_view new_state,
865 std::string_view transaction_uid = "")
866 -> VoidResult;
867
874 [[nodiscard]] auto find_ups_workitem(std::string_view workitem_uid) const
875 -> std::optional<ups_workitem>;
876
885 [[nodiscard]] auto search_ups_workitems(const ups_workitem_query& query) const
886 -> Result<std::vector<ups_workitem>>;
887
897 [[nodiscard]] auto delete_ups_workitem(std::string_view workitem_uid)
898 -> VoidResult;
899
905 [[nodiscard]] auto ups_workitem_count() const -> Result<size_t>;
906
913 [[nodiscard]] auto ups_workitem_count(std::string_view state) const
914 -> Result<size_t>;
915
916 // ========================================================================
917 // UPS Subscription Operations
918 // ========================================================================
919
926 [[nodiscard]] auto subscribe_ups(const ups_subscription& subscription)
927 -> Result<int64_t>;
928
936 [[nodiscard]] auto unsubscribe_ups(std::string_view subscriber_ae,
937 std::string_view workitem_uid = "")
938 -> VoidResult;
939
946 [[nodiscard]] auto get_ups_subscriptions(std::string_view subscriber_ae) const
947 -> Result<std::vector<ups_subscription>>;
948
958 [[nodiscard]] auto get_ups_subscribers(std::string_view workitem_uid) const
959 -> Result<std::vector<std::string>>;
960
961 // ========================================================================
962 // Audit Log Operations
963 // ========================================================================
964
973 [[nodiscard]] auto add_audit_log(const audit_record& record)
974 -> Result<int64_t>;
975
984 [[nodiscard]] auto query_audit_log(const audit_query& query) const
985 -> Result<std::vector<audit_record>>;
986
993 [[nodiscard]] auto find_audit_by_pk(int64_t pk) const
994 -> std::optional<audit_record>;
995
1001 [[nodiscard]] auto audit_count() const -> Result<size_t>;
1002
1011 [[nodiscard]] auto cleanup_old_audit_logs(std::chrono::hours age)
1012 -> Result<size_t>;
1013
1014 // ========================================================================
1015 // Database Information
1016 // ========================================================================
1017
1023 [[nodiscard]] auto path() const -> std::string_view;
1024
1030 [[nodiscard]] auto schema_version() const -> int;
1031
1037 [[nodiscard]] auto is_open() const noexcept -> bool;
1038
1039 // ========================================================================
1040 // File Path Lookup Operations
1041 // ========================================================================
1042
1052 [[nodiscard]] auto get_file_path(std::string_view sop_instance_uid) const
1053 -> Result<std::optional<std::string>>;
1054
1064 [[nodiscard]] auto get_study_files(std::string_view study_instance_uid) const
1065 -> Result<std::vector<std::string>>;
1066
1075 [[nodiscard]] auto get_series_files(std::string_view series_instance_uid) const
1076 -> Result<std::vector<std::string>>;
1077
1078 // ========================================================================
1079 // Database Maintenance Operations
1080 // ========================================================================
1081
1094 [[nodiscard]] auto vacuum() -> VoidResult;
1095
1105 [[nodiscard]] auto analyze() -> VoidResult;
1106
1115 [[nodiscard]] auto verify_integrity() const -> VoidResult;
1116
1127 [[nodiscard]] auto native_handle() const noexcept -> sqlite3*;
1128
1129#ifdef PACS_WITH_DATABASE_SYSTEM
1136 [[nodiscard]] auto db_adapter() const noexcept
1137 -> std::shared_ptr<pacs_database_adapter>;
1138#endif
1139
1149 [[nodiscard]] auto checkpoint(bool truncate = false) -> VoidResult;
1150
1151 // ========================================================================
1152 // Storage Statistics
1153 // ========================================================================
1154
1159 size_t total_patients = 0;
1160 size_t total_studies = 0;
1161 size_t total_series = 0;
1162 size_t total_instances = 0;
1163 int64_t total_file_size = 0;
1164 int64_t database_size = 0;
1165 };
1166
1174 [[nodiscard]] auto get_storage_stats() const -> Result<storage_stats>;
1175
1176private:
1180 explicit index_database(sqlite3* db, std::string path);
1181
1185 [[nodiscard]] auto parse_patient_row(void* stmt) const -> patient_record;
1186
1190 [[nodiscard]] auto parse_study_row(void* stmt) const -> study_record;
1191
1195 [[nodiscard]] auto parse_series_row(void* stmt) const -> series_record;
1196
1200 [[nodiscard]] auto parse_instance_row(void* stmt) const -> instance_record;
1201
1205 [[nodiscard]] auto parse_mpps_row(void* stmt) const -> mpps_record;
1206
1210 [[nodiscard]] auto parse_worklist_row(void* stmt) const -> worklist_item;
1211
1215 [[nodiscard]] auto parse_ups_workitem_row(void* stmt) const -> ups_workitem;
1216
1220 [[nodiscard]] auto parse_audit_row(void* stmt) const -> audit_record;
1221
1227 [[nodiscard]] static auto to_like_pattern(std::string_view pattern)
1228 -> std::string;
1229
1230#ifdef PACS_WITH_DATABASE_SYSTEM
1233 mutable std::shared_ptr<pacs_database_adapter> db_adapter_;
1234
1238 [[nodiscard]] auto initialize_database_system() -> VoidResult;
1239
1243 [[nodiscard]] auto parse_patient_from_row(
1244 const std::map<std::string, database::core::database_value>& row) const
1245 -> patient_record;
1246
1250 [[nodiscard]] auto parse_study_from_row(
1251 const std::map<std::string, database::core::database_value>& row) const
1252 -> study_record;
1253
1257 [[nodiscard]] auto parse_series_from_row(
1258 const std::map<std::string, database::core::database_value>& row) const
1259 -> series_record;
1260
1264 [[nodiscard]] auto parse_instance_from_row(
1265 const std::map<std::string, database::core::database_value>& row) const
1266 -> instance_record;
1267
1271 [[nodiscard]] auto parse_mpps_from_row(
1272 const std::map<std::string, database::core::database_value>& row) const
1273 -> mpps_record;
1274
1278 [[nodiscard]] auto parse_worklist_from_row(
1279 const std::map<std::string, database::core::database_value>& row) const
1280 -> worklist_item;
1281
1285 [[nodiscard]] auto parse_audit_from_row(
1286 const std::map<std::string, database::core::database_value>& row) const
1287 -> audit_record;
1288
1297 [[nodiscard]] auto initialize_database_adapter() -> VoidResult;
1298
1302 [[nodiscard]] auto parse_patient_from_adapter_row(
1303 const database_row& row) const -> patient_record;
1304
1308 [[nodiscard]] auto parse_study_from_adapter_row(
1309 const database_row& row) const -> study_record;
1310
1314 [[nodiscard]] auto parse_series_from_adapter_row(
1315 const database_row& row) const -> series_record;
1316
1320 [[nodiscard]] auto parse_instance_from_adapter_row(
1321 const database_row& row) const -> instance_record;
1322
1326 [[nodiscard]] auto parse_mpps_from_adapter_row(
1327 const database_row& row) const -> mpps_record;
1328
1332 [[nodiscard]] auto parse_worklist_from_adapter_row(
1333 const database_row& row) const -> worklist_item;
1334#endif
1335
1339 [[nodiscard]] auto initialize_repositories() -> VoidResult;
1340
1342 sqlite3* db_{nullptr};
1343
1345 std::string path_;
1346
1348 bool remove_on_close_{false};
1349
1351 mutable std::shared_ptr<patient_repository> patient_repository_;
1352 mutable std::shared_ptr<study_repository> study_repository_;
1353 mutable std::shared_ptr<series_repository> series_repository_;
1354 mutable std::shared_ptr<instance_repository> instance_repository_;
1355 mutable std::shared_ptr<mpps_repository> mpps_repository_;
1356 mutable std::shared_ptr<worklist_repository> worklist_repository_;
1357 mutable std::shared_ptr<ups_repository> ups_repository_;
1358 mutable std::shared_ptr<audit_repository> audit_repository_;
1359
1362};
1363
1364} // namespace kcenon::pacs::storage
Audit log record data structures.
PACS index database manager.
std::shared_ptr< mpps_repository > mpps_repository_
auto find_patient(std::string_view patient_id) const -> std::optional< patient_record >
Find a patient by patient ID.
auto cleanup_old_audit_logs(std::chrono::hours age) -> Result< size_t >
Cleanup old audit log entries.
auto list_active_mpps(std::string_view station_ae) const -> Result< std::vector< mpps_record > >
List active (IN PROGRESS) MPPS records for a station.
auto find_patient_by_pk(int64_t pk) const -> std::optional< patient_record >
Find a patient by primary key.
auto verify_integrity() const -> VoidResult
Verify database integrity.
auto patient_count() const -> Result< size_t >
Get total patient count.
auto parse_series_row(void *stmt) const -> series_record
Parse a series record from a prepared statement.
auto vacuum() -> VoidResult
Reclaim unused space in the database.
auto delete_series(std::string_view series_uid) -> VoidResult
Delete a series by Series Instance UID.
auto get_ups_subscriptions(std::string_view subscriber_ae) const -> Result< std::vector< ups_subscription > >
Get all subscriptions for a subscriber.
index_database(const index_database &)=delete
auto find_instance_by_pk(int64_t pk) const -> std::optional< instance_record >
Find an instance by primary key.
auto find_ups_workitem(std::string_view workitem_uid) const -> std::optional< ups_workitem >
Find a UPS workitem by SOP Instance UID.
auto parse_study_row(void *stmt) const -> study_record
Parse a study record from a prepared statement.
auto find_study_by_pk(int64_t pk) const -> std::optional< study_record >
Find a study by primary key.
auto study_count() const -> Result< size_t >
Get total study count.
auto find_audit_by_pk(int64_t pk) const -> std::optional< audit_record >
Find an audit log entry by primary key.
auto list_instances(std::string_view series_uid) const -> Result< std::vector< instance_record > >
List all instances for a series.
auto search_ups_workitems(const ups_workitem_query &query) const -> Result< std::vector< ups_workitem > >
Search UPS workitems with query criteria.
auto search_mpps(const mpps_query &query) const -> Result< std::vector< mpps_record > >
Search MPPS records with query criteria.
auto get_ups_subscribers(std::string_view workitem_uid) const -> Result< std::vector< std::string > >
Get all subscribers for a workitem.
std::shared_ptr< audit_repository > audit_repository_
auto list_series(std::string_view study_uid) const -> Result< std::vector< series_record > >
List all series for a study.
std::shared_ptr< patient_repository > patient_repository_
Extracted repositories used by the facade API.
auto find_series_by_pk(int64_t pk) const -> std::optional< series_record >
Find a series by primary key.
auto query_audit_log(const audit_query &query) const -> Result< std::vector< audit_record > >
Query audit log entries.
std::shared_ptr< study_repository > study_repository_
auto find_mpps_by_study(std::string_view study_uid) const -> Result< std::vector< mpps_record > >
Find MPPS records by Study Instance UID.
std::shared_ptr< worklist_repository > worklist_repository_
auto find_worklist_item(std::string_view step_id, std::string_view accession_no) const -> std::optional< worklist_item >
Find a worklist item by step ID and accession number.
auto operator=(const index_database &) -> index_database &=delete
std::shared_ptr< ups_repository > ups_repository_
auto update_modalities_in_study(int64_t study_pk) -> VoidResult
Update modalities in study (denormalized field)
auto upsert_instance(int64_t series_pk, std::string_view sop_uid, std::string_view sop_class_uid, std::string_view file_path, int64_t file_size, std::string_view transfer_syntax="", std::optional< int > instance_number=std::nullopt) -> Result< int64_t >
Insert or update an instance record.
auto delete_ups_workitem(std::string_view workitem_uid) -> VoidResult
Delete a UPS workitem.
auto search_studies(const study_query &query) const -> Result< std::vector< study_record > >
Search studies with query criteria.
auto parse_ups_workitem_row(void *stmt) const -> ups_workitem
Parse a UPS workitem record from a prepared statement.
std::shared_ptr< instance_repository > instance_repository_
auto parse_mpps_row(void *stmt) const -> mpps_record
Parse an MPPS record from a prepared statement.
auto delete_worklist_item(std::string_view step_id, std::string_view accession_no) -> VoidResult
Delete a worklist item.
auto parse_instance_row(void *stmt) const -> instance_record
Parse an instance record from a prepared statement.
auto get_series_files(std::string_view series_instance_uid) const -> Result< std::vector< std::string > >
Get all file paths for a series.
auto parse_worklist_row(void *stmt) const -> worklist_item
Parse a worklist record from a prepared statement.
auto delete_patient(std::string_view patient_id) -> VoidResult
Delete a patient by patient ID.
auto series_count() const -> Result< size_t >
Get total series count.
auto native_handle() const noexcept -> sqlite3 *
Get the raw SQLite database handle.
auto create_mpps(std::string_view mpps_uid, std::string_view station_ae="", std::string_view modality="", std::string_view study_uid="", std::string_view accession_no="", std::string_view start_datetime="") -> Result< int64_t >
Create a new MPPS record (N-CREATE)
auto is_open() const noexcept -> bool
Check if the database is open.
auto upsert_patient(std::string_view patient_id, std::string_view patient_name="", std::string_view birth_date="", std::string_view sex="") -> Result< int64_t >
Insert or update a patient record.
static auto open(std::string_view db_path) -> Result< std::unique_ptr< index_database > >
Open or create a database with default configuration.
auto parse_audit_row(void *stmt) const -> audit_record
Parse an audit record from a prepared statement.
auto ups_workitem_count() const -> Result< size_t >
Get total UPS workitem count.
auto subscribe_ups(const ups_subscription &subscription) -> Result< int64_t >
Subscribe to UPS workitem events.
auto add_audit_log(const audit_record &record) -> Result< int64_t >
Add a new audit log entry.
auto upsert_series(int64_t study_pk, std::string_view series_uid, std::string_view modality="", std::optional< int > series_number=std::nullopt, std::string_view series_description="", std::string_view body_part_examined="", std::string_view station_name="") -> Result< int64_t >
Insert or update a series record.
auto audit_count() const -> Result< size_t >
Get total audit log count.
auto update_worklist_status(std::string_view step_id, std::string_view accession_no, std::string_view new_status) -> VoidResult
Update worklist item status.
auto analyze() -> VoidResult
Update database statistics for query optimization.
auto cleanup_old_worklist_items(std::chrono::hours age) -> Result< size_t >
Cleanup old worklist items.
auto list_studies(std::string_view patient_id) const -> Result< std::vector< study_record > >
List all studies for a patient.
auto update_ups_workitem(const ups_workitem &workitem) -> VoidResult
Update an existing UPS workitem.
std::string path_
Database file path.
auto change_ups_state(std::string_view workitem_uid, std::string_view new_state, std::string_view transaction_uid="") -> VoidResult
Change UPS workitem state.
auto find_study(std::string_view study_uid) const -> std::optional< study_record >
Find a study by Study Instance UID.
auto update_mpps(std::string_view mpps_uid, std::string_view new_status, std::string_view end_datetime="", std::string_view performed_series="") -> VoidResult
Update an existing MPPS record (N-SET)
auto query_worklist(const worklist_query &query) const -> Result< std::vector< worklist_item > >
Query worklist items.
auto worklist_count() const -> Result< size_t >
Get total worklist count.
bool remove_on_close_
Remove the backing file on destruction for adapter-compatible memory DBs.
auto parse_patient_row(void *stmt) const -> patient_record
Parse a patient record from a prepared statement.
auto path() const -> std::string_view
Get the database file path.
auto delete_mpps(std::string_view mpps_uid) -> VoidResult
Delete an MPPS record.
auto search_instances(const instance_query &query) const -> Result< std::vector< instance_record > >
Search instances with query criteria.
auto unsubscribe_ups(std::string_view subscriber_ae, std::string_view workitem_uid="") -> VoidResult
Unsubscribe from UPS workitem events.
auto find_worklist_by_pk(int64_t pk) const -> std::optional< worklist_item >
Find a worklist item by primary key.
auto find_series(std::string_view series_uid) const -> std::optional< series_record >
Find a series by Series Instance UID.
auto create_ups_workitem(const ups_workitem &workitem) -> Result< int64_t >
Create a new UPS workitem (N-CREATE)
auto get_study_files(std::string_view study_instance_uid) const -> Result< std::vector< std::string > >
Get all file paths for a study.
auto instance_count() const -> Result< size_t >
Get total instance count.
migration_runner migration_runner_
Migration runner for schema management.
auto search_series(const series_query &query) const -> Result< std::vector< series_record > >
Search series with query criteria.
auto find_instance(std::string_view sop_uid) const -> std::optional< instance_record >
Find an instance by SOP Instance UID.
auto get_file_path(std::string_view sop_instance_uid) const -> Result< std::optional< std::string > >
Get file path for a SOP Instance UID.
auto delete_study(std::string_view study_uid) -> VoidResult
Delete a study by Study Instance UID.
auto checkpoint(bool truncate=false) -> VoidResult
Checkpoint WAL file.
auto schema_version() const -> int
Get the current schema version.
auto delete_instance(std::string_view sop_uid) -> VoidResult
Delete an instance by SOP Instance UID.
sqlite3 * db_
SQLite database handle (used for migrations and fallback)
auto cleanup_worklist_items_before(std::chrono::system_clock::time_point before) -> Result< size_t >
Cleanup worklist items scheduled before a specific time.
auto find_mpps_by_pk(int64_t pk) const -> std::optional< mpps_record >
Find an MPPS by primary key.
auto add_worklist_item(const worklist_item &item) -> Result< int64_t >
Add a new worklist item.
std::shared_ptr< series_repository > series_repository_
auto mpps_count() const -> Result< size_t >
Get total MPPS count.
auto search_patients(const patient_query &query) const -> Result< std::vector< patient_record > >
Search patients with query criteria.
static auto to_like_pattern(std::string_view pattern) -> std::string
Convert wildcard pattern to SQL LIKE pattern.
auto get_storage_stats() const -> Result< storage_stats >
Get storage statistics.
auto upsert_study(int64_t patient_pk, std::string_view study_uid, std::string_view study_id="", std::string_view study_date="", std::string_view study_time="", std::string_view accession_number="", std::string_view referring_physician="", std::string_view study_description="") -> Result< int64_t >
Insert or update a study record.
~index_database()
Destructor - closes database connection.
auto initialize_repositories() -> VoidResult
Initialize extracted repositories for facade delegation.
auto find_mpps(std::string_view mpps_uid) const -> std::optional< mpps_record >
Find an MPPS by SOP Instance UID.
Manages database schema migrations.
Instance record data structures for database operations.
Database schema migration runner.
MPPS (Modality Performed Procedure Step) record data structures.
Unified database adapter for PACS system.
Patient record data structures for database operations.
Series record data structures for database operations.
Query parameters for audit log search.
Audit log record from the database.
Configuration for index database.
size_t mmap_size
Maximum memory map size in bytes (default: 1 GB)
size_t cache_size_mb
Cache size in megabytes (default: 64 MB)
bool wal_mode
Enable WAL (Write-Ahead Logging) mode for better concurrency.
bool mmap_enabled
Enable memory-mapped I/O for faster reads.
int64_t total_file_size
Total size of all files in bytes.
int64_t database_size
Size of the database file in bytes.
Query parameters for instance search.
Instance record from the database.
Query parameters for MPPS search.
MPPS record from the database.
Query parameters for patient search.
Patient record from the database.
Query parameters for series search.
Series record from the database.
Query parameters for study search.
Study record from the database.
UPS subscription record from the database.
Query parameters for UPS workitem search.
UPS workitem record from the database.
Worklist item record from the database.
Query parameters for worklist search.
Study record data structures for database operations.
Unified Procedure Step (UPS) workitem data structures.
Modality Worklist (MWL) record data structures.