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