1extern crate self as icydb;
61
62pub use icydb_model_macros::{request_execution, test};
63
64#[doc(hidden)]
66pub use icydb_core::types;
67
68pub mod value {
69 pub use icydb_core::value::{
70 InputValue, InputValueEnum, OutputValue, OutputValueEnum, ValueTag,
71 };
72}
73
74#[doc(hidden)]
75pub mod metrics {
76 pub use icydb_core::metrics::{
77 CompactEntityMetrics, CompactEventCounters, CompactMetric, CompactMetricsReport,
78 EntitySummary, EventCounters, EventOps, EventReport, MetricRatio, MetricsSink,
79 compact_metric_code, compact_metrics_report, metrics_report, metrics_reset_all,
80 };
81}
82
83#[cfg(not(target_arch = "wasm32"))]
85pub mod build {
86 pub use crate::build_canister;
94
95 #[doc(hidden)]
104 pub fn __emit_canister_for_build_script(
105 canister_path: &str,
106 ) -> Result<(), Box<dyn std::error::Error>> {
107 println!("cargo:rerun-if-changed=build.rs");
108 println!("cargo:rustc-check-cfg=cfg(feature, values(\"test-admin-api\"))");
109 let out_dir = std::env::var("OUT_DIR")?;
110 let actor_file = std::path::PathBuf::from(out_dir).join("actor.rs");
111 let actor = icydb_model::build::generate(canister_path);
112 std::fs::write(actor_file, actor)?;
113
114 Ok(())
115 }
116}
117pub mod db;
118pub mod guards;
119pub mod diagnostic {
120 pub use icydb_diagnostic_code::{
123 Diagnostic, DiagnosticAggregateKind, DiagnosticBacklogResource, DiagnosticCode,
124 DiagnosticComponentKind, DiagnosticConstraintContext, DiagnosticConstraintKind,
125 DiagnosticDecodeReason, DiagnosticDetail, DiagnosticExecutionBudgetResource,
126 DiagnosticExecutionBudgetScope, DiagnosticExecutionLane, DiagnosticFactSchemaMismatch,
127 DiagnosticFactTag, DiagnosticFunctionKind, DiagnosticMutationOperation,
128 DiagnosticOperatorKind, DiagnosticTypeFamily, ErrorClass, ErrorCode, ErrorOrigin,
129 MAX_PUBLIC_DIAGNOSTIC_FACTS, MAX_PUBLIC_QUERY_FIELD_BYTES, QueryErrorKind, QueryFieldRole,
130 QueryFieldSchemaMismatch, QueryProjectionCode, QueryReadAdmissionCode,
131 QueryResultShapeCode, RuntimeBoundaryCode, RuntimeErrorKind, SchemaDdlAdmissionCode,
132 SchemaMigrationCode, SqlFeatureCode, SqlLoweringCode, SqlSurfaceMismatchCode,
133 SqlWriteBoundaryCode, pack_u32_pair, unpack_u32_pair,
134 validate_known_diagnostic_fact_schema, validate_query_field_schema,
135 validate_raw_diagnostic_fact_schema,
136 };
137}
138mod error;
139pub mod traits;
140pub use error::{
141 ConstraintValidationFindingOutput, ConstraintValuePath, ConstraintValuePathComponent,
142 DiagnosticFact, Error, ErrorKind, ErrorOrigin, QueryErrorKind, QueryFieldDiagnostic,
143 RuntimeErrorKind,
144};
145pub use guards::{
146 ReadAuthorizationContext, ReadAuthorizationDecision, ReadAuthorizationGuard,
147 ReadAuthorizationSurface,
148};
149pub use icydb_diagnostic_code::ErrorCode;
150
151#[doc(hidden)]
154pub mod __macro {
155 pub use crate::db::{
156 TypedFieldBindingRequest, TypedFieldType, ensure_default_memory_manager,
157 execute_generated_storage_report,
158 };
159 pub use crate::guards::{authorize_schema_read, authorize_sql_read};
160 pub use ic_memory::{ic_memory_declaration, ic_memory_key, ic_memory_range};
161 pub use icydb_core::db::{
162 CompositePrimaryKeyValue, DataStore, DbSession as CoreDbSession, EntityKey, EntityKeyBytes,
163 EntityKeyBytesError, IndexStore, JournalTailStore, KeyValueCodec, PrimaryKeyDecode,
164 PrimaryKeyEncode, PrimaryKeyEncodeError, PrimaryKeyValue, SchemaStore,
165 StoreAllocationIdentities, StoreAllocationIdentity, StoreRegistry,
166 StoreRuntimeStorageCapabilities, validate_entity_key_bytes_buffer,
167 };
168 #[cfg(feature = "sql")]
169 pub use icydb_core::db::{sql_statement_dispatch, sql_statement_entity_name};
170 pub use icydb_core::error::{ErrorClass, ErrorOrigin, InternalError};
171 pub use icydb_core::metrics::with_query_metrics_context;
172 pub use icydb_core::traits::{CanisterKind, Path};
173 pub use icydb_core::value::Value;
174 pub use icydb_schema::{DEFAULT_BIG_INT_MAX_BYTES, ScalarType};
175}
176
177#[doc(hidden)]
180pub mod __reexports {
181 pub use candid;
182 pub use ic_cdk;
183 pub use ic_timers;
184}
185
186pub mod prelude {
192 pub use crate::db::{
193 query,
194 query::{
195 FieldRef, FilterExpr, FilterValue, OrderExpr, OrderTerm, asc, count, count_by, desc,
196 exists, field, first, last, max, max_by, min, min_by, sum,
197 },
198 };
199 pub use crate::{
200 db,
201 traits::{Inner as _, Path as _},
202 types::*,
203 value::{InputValue, OutputValue},
204 };
205 pub use candid::CandidType;
206 pub use serde::{Deserialize, Serialize};
207}
208
209pub const VERSION: &str = env!("CARGO_PKG_VERSION");
219
220#[cfg(not(target_arch = "wasm32"))]
226#[macro_export]
227macro_rules! build_canister {
228 ($canister_ty:ty) => {{
229 let _ = ::std::any::TypeId::of::<$canister_ty>();
230 $crate::build::__emit_canister_for_build_script(stringify!($canister_ty))
231 }};
232}
233
234#[macro_export]
269macro_rules! start {
270 () => {
271 $crate::__icydb_start_actor!();
272 $crate::__icydb_start_lifecycle!();
273 };
274
275 (participant) => {
276 $crate::__icydb_start_actor!();
277 $crate::__icydb_start_participant_lifecycle!();
278 };
279
280 (
281 init($($init_arg:ident : $init_ty:ty),* $(,)?) => $init:path;
282 post_upgrade($($upgrade_arg:ident : $upgrade_ty:ty),* $(,)?) => $post_upgrade:path;
283 ) => {
284 $crate::__icydb_start_actor!();
285 $crate::__icydb_start_lifecycle! {
286 init($($init_arg: $init_ty),*) => $init;
287 post_upgrade($($upgrade_arg: $upgrade_ty),*) => $post_upgrade;
288 }
289 };
290}
291
292#[doc(hidden)]
293#[macro_export]
294#[expect(
295 clippy::crate_in_macro_def,
296 reason = "participant functions must call the consuming canister's generated actor"
297)]
298macro_rules! __icydb_start_participant_lifecycle {
299 () => {
300 #[doc(hidden)]
301 #[allow(dead_code)]
302 pub(crate) mod __icydb_lifecycle_participant {
303 use std::cell::Cell;
304
305 #[derive(Clone, Copy)]
306 enum State {
307 Idle,
308 Running,
309 Completed,
310 }
311
312 std::thread_local! {
313 static STATE: Cell<State> = const { Cell::new(State::Idle) };
314 }
315
316 #[cfg(not(target_family = "wasm"))]
320 struct NativeRollbackGuard {
321 completed: bool,
322 }
323
324 #[cfg(not(target_family = "wasm"))]
325 impl NativeRollbackGuard {
326 const fn new() -> Self {
327 Self { completed: false }
328 }
329
330 const fn complete(&mut self) {
331 self.completed = true;
332 }
333 }
334
335 #[cfg(not(target_family = "wasm"))]
336 impl Drop for NativeRollbackGuard {
337 fn drop(&mut self) {
338 if !self.completed {
339 STATE.with(|state| state.set(State::Idle));
340 }
341 }
342 }
343
344 fn participate(work: fn() -> ()) {
348 let should_run = STATE.with(|state| match state.get() {
349 State::Idle => {
350 state.set(State::Running);
351 true
352 }
353 State::Running => $crate::__reexports::ic_cdk::trap(
354 "IcyDB lifecycle participant re-entered while running",
355 ),
356 State::Completed => false,
357 });
358
359 if !should_run {
360 return;
361 }
362
363 #[cfg(not(target_family = "wasm"))]
364 let mut rollback = NativeRollbackGuard::new();
365
366 work();
367 STATE.with(|state| state.set(State::Completed));
368
369 #[cfg(not(target_family = "wasm"))]
370 rollback.complete();
371 }
372
373 #[doc(hidden)]
375 pub(crate) fn init() -> () {
376 let participate: fn() -> () = crate::__icydb_generated::__icydb_startup_init;
377 self::participate(participate);
378 }
379
380 #[doc(hidden)]
382 pub(crate) fn post_upgrade() -> () {
383 let participate: fn() -> () =
384 crate::__icydb_generated::__icydb_startup_post_upgrade;
385 self::participate(participate);
386 }
387 }
388 };
389}
390
391#[doc(hidden)]
392#[macro_export]
393#[expect(
394 clippy::crate_in_macro_def,
395 reason = "lifecycle wrappers must call the consuming canister's generated actor"
396)]
397macro_rules! __icydb_start_lifecycle {
398 () => {
399 #[$crate::__reexports::ic_cdk::init(hidden = true)]
400 fn __icydb_startup_init() {
401 crate::__icydb_generated::__icydb_startup_init();
402 }
403
404 #[$crate::__reexports::ic_cdk::post_upgrade(hidden = true)]
405 fn __icydb_startup_post_upgrade() {
406 crate::__icydb_generated::__icydb_startup_post_upgrade();
407 }
408 };
409
410 (
411 init($($init_arg:ident : $init_ty:ty),* $(,)?) => $init:path;
412 post_upgrade($($upgrade_arg:ident : $upgrade_ty:ty),* $(,)?) => $post_upgrade:path;
413 ) => {
414 #[$crate::__reexports::ic_cdk::init]
415 fn __icydb_startup_init($($init_arg: $init_ty),*) {
416 crate::__icydb_generated::__icydb_startup_init();
417 let (): () = $crate::db::with_request_execution(|| ($init)($($init_arg),*));
418 }
419
420 #[$crate::__reexports::ic_cdk::post_upgrade]
421 fn __icydb_startup_post_upgrade($($upgrade_arg: $upgrade_ty),*) {
422 crate::__icydb_generated::__icydb_startup_post_upgrade();
423 let (): () = $crate::db::with_request_execution(
424 || ($post_upgrade)($($upgrade_arg),*)
425 );
426 }
427 };
428}
429
430#[doc(hidden)]
431#[macro_export]
432#[expect(
433 clippy::crate_in_macro_def,
434 reason = "generated actor bindings must live in the consuming canister crate"
435)]
436macro_rules! __icydb_start_actor {
437 () => {
438 #[doc(hidden)]
439 struct __IcydbStartRootMarker;
440
441 #[doc(hidden)]
442 const fn __icydb_start_root_binding(_: __IcydbStartRootMarker) {}
443
444 const _: fn(__IcydbStartRootMarker) = crate::__icydb_start_root_binding;
445
446 #[allow(dead_code)]
447 mod __icydb_generated {
448 #[doc(hidden)]
449 pub(crate) const __ICYDB_START_BINDING: () = ();
450
451 include!(concat!(env!("OUT_DIR"), "/actor.rs"));
452 }
453
454 #[allow(unused_imports)]
455 use __icydb_generated::{db, db_with_request_root, startup_state};
456 };
457}
458
459#[doc(hidden)]
460#[cfg(feature = "sql")]
461#[macro_export]
462macro_rules! __icydb_with_sql_items {
463 ($($item:item)*) => { $($item)* };
464}
465
466#[doc(hidden)]
467#[cfg(not(feature = "sql"))]
468#[macro_export]
469macro_rules! __icydb_with_sql_items {
470 ($($item:item)*) => {};
471}
472
473#[doc(hidden)]
474#[cfg(feature = "migration")]
475#[macro_export]
476macro_rules! __icydb_with_migration_items {
477 ($($item:item)*) => { $($item)* };
478}
479
480#[doc(hidden)]
481#[cfg(not(feature = "migration"))]
482#[macro_export]
483macro_rules! __icydb_with_migration_items {
484 ($($item:item)*) => {};
485}
486
487#[doc(hidden)]
488#[cfg(feature = "sql")]
489#[macro_export]
490macro_rules! __icydb_with_sql_endpoint {
491 ($endpoint:literal; $($item:item)*) => { $($item)* };
492}
493
494#[doc(hidden)]
495#[cfg(feature = "migration")]
496#[macro_export]
497macro_rules! __icydb_with_migration_endpoint {
498 ($endpoint:literal; $($item:item)*) => { $($item)* };
499}
500
501#[doc(hidden)]
502#[cfg(not(feature = "migration"))]
503#[macro_export]
504macro_rules! __icydb_with_migration_endpoint {
505 ($endpoint:literal; $($item:item)*) => {
506 compile_error!(concat!(
507 "endpoint declaration `",
508 $endpoint,
509 "` requires the `icydb/migration` Cargo feature"
510 ));
511 };
512}
513
514#[doc(hidden)]
515#[cfg(not(feature = "sql"))]
516#[macro_export]
517macro_rules! __icydb_with_sql_endpoint {
518 ($endpoint:literal; $($item:item)*) => {
519 compile_error!(concat!(
520 "endpoint declaration `",
521 $endpoint,
522 "` requires the `icydb/sql` Cargo feature"
523 ));
524 };
525}
526
527#[doc(hidden)]
528#[cfg(feature = "migration")]
529#[macro_export]
530macro_rules! __icydb_require_migration_capability {
531 () => {};
532}
533
534#[doc(hidden)]
535#[cfg(not(feature = "migration"))]
536#[macro_export]
537macro_rules! __icydb_require_migration_capability {
538 () => {
539 compile_error!("source migration declarations require the `icydb/migration` Cargo feature");
540 };
541}
542
543#[macro_export]
545#[expect(
546 clippy::crate_in_macro_def,
547 reason = "endpoints! must prove crate-root placement in the consuming canister"
548)]
549macro_rules! endpoints {
550 ($($declaration:tt)*) => {
551 #[doc(hidden)]
552 struct __IcydbEndpointsRootMarker;
553
554 #[doc(hidden)]
555 const fn __icydb_endpoints_root_binding(_: __IcydbEndpointsRootMarker) {}
556
557 const _: fn(__IcydbEndpointsRootMarker) = crate::__icydb_endpoints_root_binding;
558
559 #[doc(hidden)]
560 #[allow(unused_imports)]
561 use $crate as __icydb_facade;
562
563 #[used]
564 static __ICYDB_ENDPOINT_DECLARATIONS: () =
565 crate::__icydb_generated::__ICYDB_START_BINDING;
566
567 $crate::__icydb_endpoints_internal!($($declaration)*);
568 };
569}
570
571#[doc(hidden)]
572#[macro_export]
573#[expect(
574 clippy::crate_in_macro_def,
575 reason = "endpoint wrappers call the consuming canister's private generated module"
576)]
577macro_rules! __icydb_endpoints_internal {
578 () => {};
579
580 ($(#[cfg($($cfg:tt)*)])* icydb_sql_query(
581 introspection = false,
582 authorization = guard($guard:path) $(,)?
583 ); $($rest:tt)*) => {
584 $(#[cfg($($cfg)*)])*
585 #[used]
586 static __ICYDB_ENDPOINT_DECLARATION_QUERY: () = ();
587 $(#[cfg($($cfg)*)])*
588 $crate::__icydb_with_sql_endpoint! {
589 "icydb_sql_query";
590 #[$crate::__reexports::ic_cdk::query(name = "icydb_query")]
591 fn __icydb_export_icydb_query(
592 sql: String,
593 ) -> Result<__icydb_facade::db::sql::SqlQueryPerfResult, __icydb_facade::Error> {
594 let guard: $crate::ReadAuthorizationGuard = $guard;
595 $crate::__macro::authorize_sql_read(
596 $crate::__reexports::ic_cdk::api::msg_caller(),
597 guard,
598 )?;
599 $crate::__macro::with_query_metrics_context(|| {
600 $crate::db::with_request_execution(|| {
601 crate::__icydb_generated::endpoint_handlers::sql_query::<false>(sql)
602 })
603 })
604 }
605 }
606 $crate::__icydb_endpoints_internal!($($rest)*);
607 };
608
609 ($(#[cfg($($cfg:tt)*)])* icydb_sql_query(
610 introspection = true,
611 authorization = guard($guard:path) $(,)?
612 ); $($rest:tt)*) => {
613 $(#[cfg($($cfg)*)])*
614 #[used]
615 static __ICYDB_ENDPOINT_DECLARATION_QUERY: () = ();
616 $(#[cfg($($cfg)*)])*
617 $crate::__icydb_with_sql_endpoint! {
618 "icydb_sql_query";
619 #[$crate::__reexports::ic_cdk::query(name = "icydb_query")]
620 fn __icydb_export_icydb_query(
621 sql: String,
622 ) -> Result<__icydb_facade::db::sql::SqlQueryPerfResult, __icydb_facade::Error> {
623 let guard: $crate::ReadAuthorizationGuard = $guard;
624 $crate::__macro::authorize_sql_read(
625 $crate::__reexports::ic_cdk::api::msg_caller(),
626 guard,
627 )?;
628 $crate::__macro::with_query_metrics_context(|| {
629 $crate::db::with_request_execution(|| {
630 crate::__icydb_generated::endpoint_handlers::sql_query::<true>(sql)
631 })
632 })
633 }
634 }
635 $crate::__icydb_endpoints_internal!($($rest)*);
636 };
637
638 ($(#[cfg($($cfg:tt)*)])* icydb_sql_query(introspection = false); $($rest:tt)*) => {
639 $(#[cfg($($cfg)*)])*
640 #[used]
641 static __ICYDB_ENDPOINT_DECLARATION_QUERY: () = ();
642 $(#[cfg($($cfg)*)])*
643 $crate::__icydb_with_sql_endpoint! {
644 "icydb_sql_query";
645 #[$crate::__reexports::ic_cdk::query(name = "icydb_query")]
646 fn __icydb_export_icydb_query(
647 sql: String,
648 ) -> Result<__icydb_facade::db::sql::SqlQueryPerfResult, __icydb_facade::Error> {
649 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
650 $crate::__macro::with_query_metrics_context(|| {
651 $crate::db::with_request_execution(|| {
652 crate::__icydb_generated::endpoint_handlers::sql_query::<false>(sql)
653 })
654 })
655 }
656 }
657 $crate::__icydb_endpoints_internal!($($rest)*);
658 };
659
660 ($(#[cfg($($cfg:tt)*)])* icydb_sql_query(introspection = true); $($rest:tt)*) => {
661 $(#[cfg($($cfg)*)])*
662 #[used]
663 static __ICYDB_ENDPOINT_DECLARATION_QUERY: () = ();
664 $(#[cfg($($cfg)*)])*
665 $crate::__icydb_with_sql_endpoint! {
666 "icydb_sql_query";
667 #[$crate::__reexports::ic_cdk::query(name = "icydb_query")]
668 fn __icydb_export_icydb_query(
669 sql: String,
670 ) -> Result<__icydb_facade::db::sql::SqlQueryPerfResult, __icydb_facade::Error> {
671 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
672 $crate::__macro::with_query_metrics_context(|| {
673 $crate::db::with_request_execution(|| {
674 crate::__icydb_generated::endpoint_handlers::sql_query::<true>(sql)
675 })
676 })
677 }
678 }
679 $crate::__icydb_endpoints_internal!($($rest)*);
680 };
681
682 ($(#[cfg($($cfg:tt)*)])* icydb_ddl; $($rest:tt)*) => {
683 $(#[cfg($($cfg)*)])*
684 #[used]
685 static __ICYDB_ENDPOINT_DECLARATION_DDL: () = ();
686 $(#[cfg($($cfg)*)])*
687 $crate::__icydb_with_sql_endpoint! {
688 "icydb_ddl";
689 #[$crate::__reexports::ic_cdk::update(name = "icydb_ddl")]
690 fn __icydb_export_icydb_ddl(
691 sql: String,
692 ) -> Result<__icydb_facade::db::sql::SqlQueryResult, __icydb_facade::Error> {
693 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
694 $crate::db::with_request_execution(|| {
695 crate::__icydb_generated::endpoint_handlers::sql_ddl(sql)
696 })
697 }
698 }
699 $crate::__icydb_endpoints_internal!($($rest)*);
700 };
701
702 ($(#[cfg($($cfg:tt)*)])* icydb_update(admission = primary_key_only); $($rest:tt)*) => {
703 $(#[cfg($($cfg)*)])*
704 #[used]
705 static __ICYDB_ENDPOINT_DECLARATION_UPDATE: () = ();
706 $(#[cfg($($cfg)*)])*
707 $crate::__icydb_with_sql_endpoint! {
708 "icydb_update";
709 #[$crate::__reexports::ic_cdk::update(name = "icydb_update")]
710 fn __icydb_export_icydb_update(
711 sql: String,
712 ) -> Result<__icydb_facade::db::sql::SqlQueryResult, __icydb_facade::Error> {
713 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
714 $crate::db::with_request_execution(|| {
715 crate::__icydb_generated::endpoint_handlers::sql_update_primary_key(sql)
716 })
717 }
718 }
719 $crate::__icydb_endpoints_internal!($($rest)*);
720 };
721
722 ($(#[cfg($($cfg:tt)*)])* icydb_update(admission = bounded_deterministic); $($rest:tt)*) => {
723 $(#[cfg($($cfg)*)])*
724 #[used]
725 static __ICYDB_ENDPOINT_DECLARATION_UPDATE: () = ();
726 $(#[cfg($($cfg)*)])*
727 $crate::__icydb_with_sql_endpoint! {
728 "icydb_update";
729 #[$crate::__reexports::ic_cdk::update(name = "icydb_update")]
730 fn __icydb_export_icydb_update(
731 sql: String,
732 ) -> Result<__icydb_facade::db::sql::SqlQueryResult, __icydb_facade::Error> {
733 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
734 $crate::db::with_request_execution(|| {
735 crate::__icydb_generated::endpoint_handlers::sql_update_bounded(sql)
736 })
737 }
738 }
739 $crate::__icydb_endpoints_internal!($($rest)*);
740 };
741
742 ($(#[cfg($($cfg:tt)*)])* icydb_integrity; $($rest:tt)*) => {
743 $(#[cfg($($cfg)*)])*
744 #[used]
745 static __ICYDB_ENDPOINT_DECLARATION_INTEGRITY: () = ();
746 $(#[cfg($($cfg)*)])*
747 $crate::__icydb_with_sql_endpoint! {
748 "icydb_integrity";
749 #[allow(clippy::result_large_err)]
750 #[$crate::__reexports::ic_cdk::update(name = "icydb_integrity")]
751 fn __icydb_export_icydb_integrity(
752 sql: String,
753 ) -> Result<__icydb_facade::db::IntegrityCheckResult, __icydb_facade::db::SqlIntegrityError> {
754 crate::__icydb_generated::endpoint_authorization::require_sql_controller()
755 .map_err(__icydb_facade::db::SqlIntegrityError::Sql)?;
756 $crate::db::with_request_execution(|| {
757 crate::__icydb_generated::endpoint_handlers::sql_integrity(sql)
758 })
759 }
760 }
761 $crate::__icydb_endpoints_internal!($($rest)*);
762 };
763
764 ($(#[cfg($($cfg:tt)*)])* icydb_fixtures_reset; $($rest:tt)*) => {
765 $(#[cfg($($cfg)*)])*
766 #[used]
767 static __ICYDB_ENDPOINT_DECLARATION_FIXTURES_RESET: () = ();
768 $(#[cfg($($cfg)*)])*
769 #[cfg(not(feature = "test-admin-api"))]
770 compile_error!("endpoint declaration `icydb_fixtures_reset` requires the canister `test-admin-api` Cargo feature");
771 $(#[cfg($($cfg)*)])*
772 #[cfg(feature = "test-admin-api")]
773 $crate::__icydb_with_sql_endpoint! {
774 "icydb_fixtures_reset";
775 #[$crate::__reexports::ic_cdk::update(name = "icydb_fixtures_reset")]
776 fn __icydb_export_icydb_fixtures_reset() -> Result<(), __icydb_facade::Error> {
777 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
778 $crate::db::with_request_execution(|| {
779 crate::__icydb_generated::endpoint_handlers::fixtures_reset()
780 })
781 }
782 }
783 $crate::__icydb_endpoints_internal!($($rest)*);
784 };
785
786 ($(#[cfg($($cfg:tt)*)])* icydb_fixtures_load(handler = $handler:path); $($rest:tt)*) => {
787 $(#[cfg($($cfg)*)])*
788 #[used]
789 static __ICYDB_ENDPOINT_DECLARATION_FIXTURES_LOAD: () = ();
790 $(#[cfg($($cfg)*)])*
791 #[cfg(not(feature = "test-admin-api"))]
792 compile_error!("endpoint declaration `icydb_fixtures_load` requires the canister `test-admin-api` Cargo feature");
793 $(#[cfg($($cfg)*)])*
794 #[cfg(feature = "test-admin-api")]
795 $crate::__icydb_with_sql_endpoint! {
796 "icydb_fixtures_load";
797 #[$crate::__reexports::ic_cdk::update(name = "icydb_fixtures_load")]
798 fn __icydb_export_icydb_fixtures_load() -> Result<(), __icydb_facade::Error> {
799 crate::__icydb_generated::endpoint_authorization::require_sql_controller()?;
800 let handler: fn() -> Result<(), $crate::Error> = $handler;
801 $crate::db::with_request_execution(|| {
802 crate::__icydb_generated::endpoint_handlers::fixtures_load(handler)
803 })
804 }
805 }
806 $crate::__icydb_endpoints_internal!($($rest)*);
807 };
808
809 ($(#[cfg($($cfg:tt)*)])* icydb_metrics(authorization = public); $($rest:tt)*) => {
810 $(#[cfg($($cfg)*)])*
811 #[used]
812 static __ICYDB_ENDPOINT_DECLARATION_METRICS: () = ();
813 $(#[cfg($($cfg)*)])*
814 #[$crate::__reexports::ic_cdk::query(name = "icydb_metrics")]
815 fn __icydb_export_icydb_metrics(
816 window_start_ms: Option<u64>,
817 ) -> Result<__icydb_facade::metrics::CompactMetricsReport, __icydb_facade::Error> {
818 $crate::__macro::with_query_metrics_context(|| {
819 crate::__icydb_generated::endpoint_handlers::metrics(window_start_ms)
820 })
821 }
822 $crate::__icydb_endpoints_internal!($($rest)*);
823 };
824
825 ($(#[cfg($($cfg:tt)*)])* icydb_metrics(authorization = controller); $($rest:tt)*) => {
826 $(#[cfg($($cfg)*)])*
827 #[used]
828 static __ICYDB_ENDPOINT_DECLARATION_METRICS: () = ();
829 $(#[cfg($($cfg)*)])*
830 #[$crate::__reexports::ic_cdk::query(name = "icydb_metrics")]
831 fn __icydb_export_icydb_metrics(
832 window_start_ms: Option<u64>,
833 ) -> Result<__icydb_facade::metrics::CompactMetricsReport, __icydb_facade::Error> {
834 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
835 $crate::__macro::with_query_metrics_context(|| {
836 crate::__icydb_generated::endpoint_handlers::metrics(window_start_ms)
837 })
838 }
839 $crate::__icydb_endpoints_internal!($($rest)*);
840 };
841
842 ($(#[cfg($($cfg:tt)*)])* icydb_metrics_extended(authorization = public); $($rest:tt)*) => {
843 $(#[cfg($($cfg)*)])*
844 #[used]
845 static __ICYDB_ENDPOINT_DECLARATION_METRICS_EXTENDED: () = ();
846 $(#[cfg($($cfg)*)])*
847 #[$crate::__reexports::ic_cdk::query(name = "icydb_metrics_extended")]
848 fn __icydb_export_icydb_metrics_extended(
849 window_start_ms: Option<u64>,
850 ) -> Result<__icydb_facade::metrics::EventReport, __icydb_facade::Error> {
851 $crate::__macro::with_query_metrics_context(|| {
852 crate::__icydb_generated::endpoint_handlers::metrics_extended(window_start_ms)
853 })
854 }
855 $crate::__icydb_endpoints_internal!($($rest)*);
856 };
857
858 ($(#[cfg($($cfg:tt)*)])* icydb_metrics_extended(authorization = controller); $($rest:tt)*) => {
859 $(#[cfg($($cfg)*)])*
860 #[used]
861 static __ICYDB_ENDPOINT_DECLARATION_METRICS_EXTENDED: () = ();
862 $(#[cfg($($cfg)*)])*
863 #[$crate::__reexports::ic_cdk::query(name = "icydb_metrics_extended")]
864 fn __icydb_export_icydb_metrics_extended(
865 window_start_ms: Option<u64>,
866 ) -> Result<__icydb_facade::metrics::EventReport, __icydb_facade::Error> {
867 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
868 $crate::__macro::with_query_metrics_context(|| {
869 crate::__icydb_generated::endpoint_handlers::metrics_extended(window_start_ms)
870 })
871 }
872 $crate::__icydb_endpoints_internal!($($rest)*);
873 };
874
875 ($(#[cfg($($cfg:tt)*)])* icydb_metrics_reset; $($rest:tt)*) => {
876 $(#[cfg($($cfg)*)])*
877 #[used]
878 static __ICYDB_ENDPOINT_DECLARATION_METRICS_RESET: () = ();
879 $(#[cfg($($cfg)*)])*
880 #[$crate::__reexports::ic_cdk::update(name = "icydb_metrics_reset")]
881 fn __icydb_export_icydb_metrics_reset() -> Result<(), __icydb_facade::Error> {
882 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
883 crate::__icydb_generated::endpoint_handlers::metrics_reset()
884 }
885 $crate::__icydb_endpoints_internal!($($rest)*);
886 };
887
888 ($(#[cfg($($cfg:tt)*)])* icydb_snapshot; $($rest:tt)*) => {
889 $(#[cfg($($cfg)*)])*
890 #[used]
891 static __ICYDB_ENDPOINT_DECLARATION_SNAPSHOT: () = ();
892 $(#[cfg($($cfg)*)])*
893 #[$crate::__reexports::ic_cdk::query(name = "icydb_snapshot")]
894 fn __icydb_export_icydb_snapshot() -> Result<__icydb_facade::db::StorageReport, __icydb_facade::Error> {
895 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
896 $crate::__macro::with_query_metrics_context(|| {
897 $crate::db::with_request_execution(|| {
898 crate::__icydb_generated::endpoint_handlers::snapshot()
899 })
900 })
901 }
902 $crate::__icydb_endpoints_internal!($($rest)*);
903 };
904
905 ($(#[cfg($($cfg:tt)*)])* icydb_schema(authorization = public); $($rest:tt)*) => {
906 $(#[cfg($($cfg)*)])*
907 #[used]
908 static __ICYDB_ENDPOINT_DECLARATION_SCHEMA: () = ();
909 $(#[cfg($($cfg)*)])*
910 #[$crate::__reexports::ic_cdk::query(name = "icydb_schema")]
911 fn __icydb_export_icydb_schema(
912 ) -> Result<Vec<__icydb_facade::db::EntitySchemaDescription>, __icydb_facade::Error> {
913 $crate::__macro::with_query_metrics_context(|| {
914 $crate::db::with_request_execution(|| {
915 crate::__icydb_generated::endpoint_handlers::schema()
916 })
917 })
918 }
919 $crate::__icydb_endpoints_internal!($($rest)*);
920 };
921
922 ($(#[cfg($($cfg:tt)*)])* icydb_schema(
923 authorization = guard($guard:path) $(,)?
924 ); $($rest:tt)*) => {
925 $(#[cfg($($cfg)*)])*
926 #[used]
927 static __ICYDB_ENDPOINT_DECLARATION_SCHEMA: () = ();
928 $(#[cfg($($cfg)*)])*
929 #[$crate::__reexports::ic_cdk::query(name = "icydb_schema")]
930 fn __icydb_export_icydb_schema(
931 ) -> Result<Vec<__icydb_facade::db::EntitySchemaDescription>, __icydb_facade::Error> {
932 let guard: $crate::ReadAuthorizationGuard = $guard;
933 $crate::__macro::authorize_schema_read(
934 $crate::__reexports::ic_cdk::api::msg_caller(),
935 guard,
936 )?;
937 $crate::__macro::with_query_metrics_context(|| {
938 $crate::db::with_request_execution(|| {
939 crate::__icydb_generated::endpoint_handlers::schema()
940 })
941 })
942 }
943 $crate::__icydb_endpoints_internal!($($rest)*);
944 };
945
946 ($(#[cfg($($cfg:tt)*)])* icydb_schema(authorization = controller); $($rest:tt)*) => {
947 $(#[cfg($($cfg)*)])*
948 #[used]
949 static __ICYDB_ENDPOINT_DECLARATION_SCHEMA: () = ();
950 $(#[cfg($($cfg)*)])*
951 #[$crate::__reexports::ic_cdk::query(name = "icydb_schema")]
952 fn __icydb_export_icydb_schema(
953 ) -> Result<Vec<__icydb_facade::db::EntitySchemaDescription>, __icydb_facade::Error> {
954 crate::__icydb_generated::endpoint_authorization::require_schema_controller()?;
955 $crate::__macro::with_query_metrics_context(|| {
956 $crate::db::with_request_execution(|| {
957 crate::__icydb_generated::endpoint_handlers::schema()
958 })
959 })
960 }
961 $crate::__icydb_endpoints_internal!($($rest)*);
962 };
963
964 ($(#[cfg($($cfg:tt)*)])* icydb_schema_migrate; $($rest:tt)*) => {
965 $(#[cfg($($cfg)*)])*
966 #[used]
967 static __ICYDB_ENDPOINT_DECLARATION_SCHEMA_MIGRATE: () = ();
968 $(#[cfg($($cfg)*)])*
969 $crate::__icydb_with_migration_endpoint! {
970 "icydb_schema_migrate";
971 #[$crate::__reexports::ic_cdk::update(name = "icydb_schema_migrate")]
972 fn __icydb_export_icydb_schema_migrate(
973 command: __icydb_facade::db::SchemaMigrationCommand,
974 ) -> Result<__icydb_facade::db::SchemaMigrationStatusPage, __icydb_facade::Error> {
975 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
976 $crate::db::with_request_execution(|| {
977 crate::__icydb_generated::endpoint_handlers::schema_migrate(command)
978 })
979 }
980 }
981 $crate::__icydb_endpoints_internal!($($rest)*);
982 };
983
984 ($(#[cfg($($cfg:tt)*)])* icydb_schema_migration; $($rest:tt)*) => {
985 $(#[cfg($($cfg)*)])*
986 #[used]
987 static __ICYDB_ENDPOINT_DECLARATION_SCHEMA_MIGRATION: () = ();
988 $(#[cfg($($cfg)*)])*
989 $crate::__icydb_with_migration_endpoint! {
990 "icydb_schema_migration";
991 #[$crate::__reexports::ic_cdk::query(name = "icydb_schema_migration")]
992 fn __icydb_export_icydb_schema_migration(
993 request: __icydb_facade::db::SchemaMigrationStatusRequest,
994 ) -> Result<__icydb_facade::db::SchemaMigrationStatusPage, __icydb_facade::Error> {
995 crate::__icydb_generated::endpoint_authorization::require_operational_controller()?;
996 $crate::__macro::with_query_metrics_context(|| {
997 $crate::db::with_request_execution(|| {
998 crate::__icydb_generated::endpoint_handlers::schema_migration(&request)
999 })
1000 })
1001 }
1002 }
1003 $crate::__icydb_endpoints_internal!($($rest)*);
1004 };
1005
1006 ($(#[cfg($($cfg:tt)*)])* $endpoint:ident $($rest:tt)*) => {
1007 compile_error!(concat!("unknown or invalid IcyDB endpoint declaration `", stringify!($endpoint), "`"));
1008 };
1009
1010 (#[$attribute:meta] $($rest:tt)*) => {
1011 compile_error!("IcyDB endpoint declarations accept only `#[cfg(...)]` attributes");
1012 };
1013
1014 ($($invalid:tt)+) => {
1015 compile_error!("invalid IcyDB endpoint declaration syntax");
1016 };
1017}
1018
1019#[macro_export]
1033#[expect(clippy::crate_in_macro_def)]
1034macro_rules! db {
1035 () => {
1036 crate::db()
1037 };
1038 ($request_root:expr) => {
1039 crate::db_with_request_root($request_root)
1040 };
1041}
1042
1043#[cfg(all(test, not(target_arch = "wasm32")))]
1048mod tests {
1049 use crate::build;
1050
1051 struct ModelWrapper(u64);
1052
1053 impl icydb_model::Inner<u64> for ModelWrapper {
1054 fn inner(&self) -> &u64 {
1055 &self.0
1056 }
1057
1058 fn into_inner(self) -> u64 {
1059 self.0
1060 }
1061 }
1062
1063 #[test]
1064 fn build_facade_exports_typed_entrypoint() {
1065 fn assert_model_inner<T: crate::traits::Inner<u64>>() {}
1066
1067 assert_model_inner::<ModelWrapper>();
1068 let wrapper = ModelWrapper(7);
1069 assert_eq!(*crate::traits::Inner::inner(&wrapper), 7);
1070 assert_eq!(crate::traits::Inner::into_inner(wrapper), 7);
1071
1072 std::hint::black_box(
1073 build_facade_macros_resolve as fn() -> Result<(), Box<dyn std::error::Error>>,
1074 );
1075 }
1076
1077 fn build_facade_macros_resolve() -> Result<(), Box<dyn std::error::Error>> {
1078 build::build_canister!(())?;
1079
1080 Ok(())
1081 }
1082}