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
148 [[nodiscard]] static auto open(std::string_view db_path,
149 const index_config& config)
151
156
157 // Non-copyable, movable
159 auto operator=(const index_database&) -> index_database& = delete;
160 index_database(index_database&&) noexcept;
161 auto operator=(index_database&&) noexcept -> index_database&;
162
163 // ========================================================================
164 // Patient Operations
165 // ========================================================================
166
179 [[nodiscard]] auto upsert_patient(std::string_view patient_id,
180 std::string_view patient_name = "",
181 std::string_view birth_date = "",
182 std::string_view sex = "")
183 -> Result<int64_t>;
184
191 [[nodiscard]] auto upsert_patient(const patient_record& record)
192 -> Result<int64_t>;
193
200 [[nodiscard]] auto find_patient(std::string_view patient_id) const
201 -> std::optional<patient_record>;
202
209 [[nodiscard]] auto find_patient_by_pk(int64_t pk) const
210 -> std::optional<patient_record>;
211
223 [[nodiscard]] auto search_patients(const patient_query& query) const
224 -> Result<std::vector<patient_record>>;
225
235 [[nodiscard]] auto delete_patient(std::string_view patient_id)
236 -> VoidResult;
237
243 [[nodiscard]] auto patient_count() const -> Result<size_t>;
244
245 // ========================================================================
246 // Study Operations
247 // ========================================================================
248
265 [[nodiscard]] auto upsert_study(int64_t patient_pk,
266 std::string_view study_uid,
267 std::string_view study_id = "",
268 std::string_view study_date = "",
269 std::string_view study_time = "",
270 std::string_view accession_number = "",
271 std::string_view referring_physician = "",
272 std::string_view study_description = "")
273 -> Result<int64_t>;
274
281 [[nodiscard]] auto upsert_study(const study_record& record)
282 -> Result<int64_t>;
283
290 [[nodiscard]] auto find_study(std::string_view study_uid) const
291 -> std::optional<study_record>;
292
299 [[nodiscard]] auto find_study_by_pk(int64_t pk) const
300 -> std::optional<study_record>;
301
308 [[nodiscard]] auto list_studies(std::string_view patient_id) const
309 -> Result<std::vector<study_record>>;
310
320 [[nodiscard]] auto search_studies(const study_query& query) const
321 -> Result<std::vector<study_record>>;
322
331 [[nodiscard]] auto delete_study(std::string_view study_uid) -> VoidResult;
332
338 [[nodiscard]] auto study_count() const -> Result<size_t>;
339
346 [[nodiscard]] auto study_count(std::string_view patient_id) const -> Result<size_t>;
347
356 [[nodiscard]] auto update_modalities_in_study(int64_t study_pk)
357 -> VoidResult;
358
359 // ========================================================================
360 // Series Operations
361 // ========================================================================
362
378 [[nodiscard]] auto upsert_series(int64_t study_pk,
379 std::string_view series_uid,
380 std::string_view modality = "",
381 std::optional<int> series_number = std::nullopt,
382 std::string_view series_description = "",
383 std::string_view body_part_examined = "",
384 std::string_view station_name = "")
385 -> Result<int64_t>;
386
393 [[nodiscard]] auto upsert_series(const series_record& record)
394 -> Result<int64_t>;
395
402 [[nodiscard]] auto find_series(std::string_view series_uid) const
403 -> std::optional<series_record>;
404
411 [[nodiscard]] auto find_series_by_pk(int64_t pk) const
412 -> std::optional<series_record>;
413
420 [[nodiscard]] auto list_series(std::string_view study_uid) const
421 -> Result<std::vector<series_record>>;
422
432 [[nodiscard]] auto search_series(const series_query& query) const
433 -> Result<std::vector<series_record>>;
434
443 [[nodiscard]] auto delete_series(std::string_view series_uid) -> VoidResult;
444
450 [[nodiscard]] auto series_count() const -> Result<size_t>;
451
458 [[nodiscard]] auto series_count(std::string_view study_uid) const -> Result<size_t>;
459
460 // ========================================================================
461 // Instance Operations
462 // ========================================================================
463
479 [[nodiscard]] auto upsert_instance(int64_t series_pk,
480 std::string_view sop_uid,
481 std::string_view sop_class_uid,
482 std::string_view file_path,
483 int64_t file_size,
484 std::string_view transfer_syntax = "",
485 std::optional<int> instance_number = std::nullopt)
486 -> Result<int64_t>;
487
494 [[nodiscard]] auto upsert_instance(const instance_record& record)
495 -> Result<int64_t>;
496
503 [[nodiscard]] auto find_instance(std::string_view sop_uid) const
504 -> std::optional<instance_record>;
505
512 [[nodiscard]] auto find_instance_by_pk(int64_t pk) const
513 -> std::optional<instance_record>;
514
521 [[nodiscard]] auto list_instances(std::string_view series_uid) const
522 -> Result<std::vector<instance_record>>;
523
532 [[nodiscard]] auto search_instances(const instance_query& query) const
533 -> Result<std::vector<instance_record>>;
534
541 [[nodiscard]] auto delete_instance(std::string_view sop_uid) -> VoidResult;
542
548 [[nodiscard]] auto instance_count() const -> Result<size_t>;
549
556 [[nodiscard]] auto instance_count(std::string_view series_uid) const -> Result<size_t>;
557
558 // ========================================================================
559 // MPPS Operations
560 // ========================================================================
561
576 [[nodiscard]] auto create_mpps(std::string_view mpps_uid,
577 std::string_view station_ae = "",
578 std::string_view modality = "",
579 std::string_view study_uid = "",
580 std::string_view accession_no = "",
581 std::string_view start_datetime = "")
582 -> Result<int64_t>;
583
590 [[nodiscard]] auto create_mpps(const mpps_record& record) -> Result<int64_t>;
591
606 [[nodiscard]] auto update_mpps(std::string_view mpps_uid,
607 std::string_view new_status,
608 std::string_view end_datetime = "",
609 std::string_view performed_series = "")
610 -> VoidResult;
611
620 [[nodiscard]] auto update_mpps(const mpps_record& record) -> VoidResult;
621
628 [[nodiscard]] auto find_mpps(std::string_view mpps_uid) const
629 -> std::optional<mpps_record>;
630
637 [[nodiscard]] auto find_mpps_by_pk(int64_t pk) const
638 -> std::optional<mpps_record>;
639
646 [[nodiscard]] auto list_active_mpps(std::string_view station_ae) const
647 -> Result<std::vector<mpps_record>>;
648
655 [[nodiscard]] auto find_mpps_by_study(std::string_view study_uid) const
656 -> Result<std::vector<mpps_record>>;
657
664 [[nodiscard]] auto search_mpps(const mpps_query& query) const
665 -> Result<std::vector<mpps_record>>;
666
673 [[nodiscard]] auto delete_mpps(std::string_view mpps_uid) -> VoidResult;
674
680 [[nodiscard]] auto mpps_count() const -> Result<size_t>;
681
688 [[nodiscard]] auto mpps_count(std::string_view status) const -> Result<size_t>;
689
690 // ========================================================================
691 // Worklist Operations
692 // ========================================================================
693
703 [[nodiscard]] auto add_worklist_item(const worklist_item& item)
704 -> Result<int64_t>;
705
717 [[nodiscard]] auto update_worklist_status(std::string_view step_id,
718 std::string_view accession_no,
719 std::string_view new_status)
720 -> VoidResult;
721
732 [[nodiscard]] auto query_worklist(const worklist_query& query) const
733 -> Result<std::vector<worklist_item>>;
734
742 [[nodiscard]] auto find_worklist_item(std::string_view step_id,
743 std::string_view accession_no) const
744 -> std::optional<worklist_item>;
745
752 [[nodiscard]] auto find_worklist_by_pk(int64_t pk) const
753 -> std::optional<worklist_item>;
754
762 [[nodiscard]] auto delete_worklist_item(std::string_view step_id,
763 std::string_view accession_no)
764 -> VoidResult;
765
775 [[nodiscard]] auto cleanup_old_worklist_items(std::chrono::hours age)
776 -> Result<size_t>;
777
800 [[nodiscard]] auto cleanup_worklist_items_before(
801 std::chrono::system_clock::time_point before) -> Result<size_t>;
802
808 [[nodiscard]] auto worklist_count() const -> Result<size_t>;
809
816 [[nodiscard]] auto worklist_count(std::string_view status) const -> Result<size_t>;
817
818 // ========================================================================
819 // UPS Workitem Operations
820 // ========================================================================
821
831 [[nodiscard]] auto create_ups_workitem(const ups_workitem& workitem)
832 -> Result<int64_t>;
833
845 [[nodiscard]] auto update_ups_workitem(const ups_workitem& workitem)
846 -> VoidResult;
847
858 [[nodiscard]] auto change_ups_state(std::string_view workitem_uid,
859 std::string_view new_state,
860 std::string_view transaction_uid = "")
861 -> VoidResult;
862
869 [[nodiscard]] auto find_ups_workitem(std::string_view workitem_uid) const
870 -> std::optional<ups_workitem>;
871
880 [[nodiscard]] auto search_ups_workitems(const ups_workitem_query& query) const
881 -> Result<std::vector<ups_workitem>>;
882
892 [[nodiscard]] auto delete_ups_workitem(std::string_view workitem_uid)
893 -> VoidResult;
894
900 [[nodiscard]] auto ups_workitem_count() const -> Result<size_t>;
901
908 [[nodiscard]] auto ups_workitem_count(std::string_view state) const
909 -> Result<size_t>;
910
911 // ========================================================================
912 // UPS Subscription Operations
913 // ========================================================================
914
921 [[nodiscard]] auto subscribe_ups(const ups_subscription& subscription)
922 -> Result<int64_t>;
923
931 [[nodiscard]] auto unsubscribe_ups(std::string_view subscriber_ae,
932 std::string_view workitem_uid = "")
933 -> VoidResult;
934
941 [[nodiscard]] auto get_ups_subscriptions(std::string_view subscriber_ae) const
942 -> Result<std::vector<ups_subscription>>;
943
953 [[nodiscard]] auto get_ups_subscribers(std::string_view workitem_uid) const
954 -> Result<std::vector<std::string>>;
955
956 // ========================================================================
957 // Audit Log Operations
958 // ========================================================================
959
968 [[nodiscard]] auto add_audit_log(const audit_record& record)
969 -> Result<int64_t>;
970
979 [[nodiscard]] auto query_audit_log(const audit_query& query) const
980 -> Result<std::vector<audit_record>>;
981
988 [[nodiscard]] auto find_audit_by_pk(int64_t pk) const
989 -> std::optional<audit_record>;
990
996 [[nodiscard]] auto audit_count() const -> Result<size_t>;
997
1006 [[nodiscard]] auto cleanup_old_audit_logs(std::chrono::hours age)
1007 -> Result<size_t>;
1008
1009 // ========================================================================
1010 // Database Information
1011 // ========================================================================
1012
1018 [[nodiscard]] auto path() const -> std::string_view;
1019
1025 [[nodiscard]] auto schema_version() const -> int;
1026
1032 [[nodiscard]] auto is_open() const noexcept -> bool;
1033
1034 // ========================================================================
1035 // File Path Lookup Operations
1036 // ========================================================================
1037
1047 [[nodiscard]] auto get_file_path(std::string_view sop_instance_uid) const
1048 -> Result<std::optional<std::string>>;
1049
1059 [[nodiscard]] auto get_study_files(std::string_view study_instance_uid) const
1060 -> Result<std::vector<std::string>>;
1061
1070 [[nodiscard]] auto get_series_files(std::string_view series_instance_uid) const
1071 -> Result<std::vector<std::string>>;
1072
1073 // ========================================================================
1074 // Database Maintenance Operations
1075 // ========================================================================
1076
1089 [[nodiscard]] auto vacuum() -> VoidResult;
1090
1100 [[nodiscard]] auto analyze() -> VoidResult;
1101
1110 [[nodiscard]] auto verify_integrity() const -> VoidResult;
1111
1122 [[nodiscard]] auto native_handle() const noexcept -> sqlite3*;
1123
1124#ifdef PACS_WITH_DATABASE_SYSTEM
1131 [[nodiscard]] auto db_adapter() const noexcept
1132 -> std::shared_ptr<pacs_database_adapter>;
1133#endif
1134
1144 [[nodiscard]] auto checkpoint(bool truncate = false) -> VoidResult;
1145
1146 // ========================================================================
1147 // Storage Statistics
1148 // ========================================================================
1149
1154 size_t total_patients = 0;
1155 size_t total_studies = 0;
1156 size_t total_series = 0;
1157 size_t total_instances = 0;
1158 int64_t total_file_size = 0;
1159 int64_t database_size = 0;
1160 };
1161
1169 [[nodiscard]] auto get_storage_stats() const -> Result<storage_stats>;
1170
1171private:
1175 explicit index_database(sqlite3* db, std::string path);
1176
1180 [[nodiscard]] auto parse_patient_row(void* stmt) const -> patient_record;
1181
1185 [[nodiscard]] auto parse_study_row(void* stmt) const -> study_record;
1186
1190 [[nodiscard]] auto parse_series_row(void* stmt) const -> series_record;
1191
1195 [[nodiscard]] auto parse_instance_row(void* stmt) const -> instance_record;
1196
1200 [[nodiscard]] auto parse_mpps_row(void* stmt) const -> mpps_record;
1201
1205 [[nodiscard]] auto parse_worklist_row(void* stmt) const -> worklist_item;
1206
1210 [[nodiscard]] auto parse_ups_workitem_row(void* stmt) const -> ups_workitem;
1211
1215 [[nodiscard]] auto parse_audit_row(void* stmt) const -> audit_record;
1216
1222 [[nodiscard]] static auto to_like_pattern(std::string_view pattern)
1223 -> std::string;
1224
1225#ifdef PACS_WITH_DATABASE_SYSTEM
1228 mutable std::shared_ptr<pacs_database_adapter> db_adapter_;
1229
1233 [[nodiscard]] auto initialize_database_system() -> VoidResult;
1234
1238 [[nodiscard]] auto parse_patient_from_row(
1239 const std::map<std::string, database::core::database_value>& row) const
1240 -> patient_record;
1241
1245 [[nodiscard]] auto parse_study_from_row(
1246 const std::map<std::string, database::core::database_value>& row) const
1247 -> study_record;
1248
1252 [[nodiscard]] auto parse_series_from_row(
1253 const std::map<std::string, database::core::database_value>& row) const
1254 -> series_record;
1255
1259 [[nodiscard]] auto parse_instance_from_row(
1260 const std::map<std::string, database::core::database_value>& row) const
1261 -> instance_record;
1262
1266 [[nodiscard]] auto parse_mpps_from_row(
1267 const std::map<std::string, database::core::database_value>& row) const
1268 -> mpps_record;
1269
1273 [[nodiscard]] auto parse_worklist_from_row(
1274 const std::map<std::string, database::core::database_value>& row) const
1275 -> worklist_item;
1276
1280 [[nodiscard]] auto parse_audit_from_row(
1281 const std::map<std::string, database::core::database_value>& row) const
1282 -> audit_record;
1283
1292 [[nodiscard]] auto initialize_database_adapter() -> VoidResult;
1293
1297 [[nodiscard]] auto parse_patient_from_adapter_row(
1298 const database_row& row) const -> patient_record;
1299
1303 [[nodiscard]] auto parse_study_from_adapter_row(
1304 const database_row& row) const -> study_record;
1305
1309 [[nodiscard]] auto parse_series_from_adapter_row(
1310 const database_row& row) const -> series_record;
1311
1315 [[nodiscard]] auto parse_instance_from_adapter_row(
1316 const database_row& row) const -> instance_record;
1317
1321 [[nodiscard]] auto parse_mpps_from_adapter_row(
1322 const database_row& row) const -> mpps_record;
1323
1327 [[nodiscard]] auto parse_worklist_from_adapter_row(
1328 const database_row& row) const -> worklist_item;
1329#endif
1330
1334 [[nodiscard]] auto initialize_repositories() -> VoidResult;
1335
1337 sqlite3* db_{nullptr};
1338
1340 std::string path_;
1341
1343 bool remove_on_close_{false};
1344
1346 mutable std::shared_ptr<patient_repository> patient_repository_;
1347 mutable std::shared_ptr<study_repository> study_repository_;
1348 mutable std::shared_ptr<series_repository> series_repository_;
1349 mutable std::shared_ptr<instance_repository> instance_repository_;
1350 mutable std::shared_ptr<mpps_repository> mpps_repository_;
1351 mutable std::shared_ptr<worklist_repository> worklist_repository_;
1352 mutable std::shared_ptr<ups_repository> ups_repository_;
1353 mutable std::shared_ptr<audit_repository> audit_repository_;
1354
1357};
1358
1359} // namespace kcenon::pacs::storage
Audit log record data structures.
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 >
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.
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.
Instance record from the database.
MPPS record from the database.
Patient record from the database.
Series record from the database.
Study record from the database.
UPS subscription record from the database.
UPS workitem record from the database.
Worklist item record from the database.
Study record data structures for database operations.
Unified Procedure Step (UPS) workitem data structures.
Modality Worklist (MWL) record data structures.