1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! # IC DBMS Client
//!
//! This crate exposes all the types which may be used by an external canister to interact with
//! an IC DBMS Canister instance.
//!
//! ## Available Clients
//!
//! - [`IcDbmsCanisterClient`](crate::prelude::IcDbmsCanisterClient): Client implementation to be used inside IC canisters.
//! - [`IcDbmsAgentClient`](crate::prelude::IcDbmsAgentClient): Client implementation for external systems (frontend, backend services, CLI tools) using `ic-agent`. Requires the `ic-agent` feature.
//! - [`IcDbmsPocketIcClient`](crate::prelude::IcDbmsPocketIcClient): Client implementation to be used in integration tests with the `pocket-ic` feature enabled.
//!
//! The generic interface is provided by the [`Client`](crate::prelude::Client) trait.
//!
//! ## Available Types
//!
//! You can import all the useful types and traits by using the prelude module:
//!
//! ```rust
//! use ic_dbms_client::prelude::*;
//! ```
//!
//! ### Query
//!
//! - [`AggregateFunction`](crate::prelude::AggregateFunction)
//! - [`AggregatedRow`](crate::prelude::AggregatedRow)
//! - [`AggregatedValue`](crate::prelude::AggregatedValue)
//! - [`DeleteBehavior`](crate::prelude::DeleteBehavior)
//! - [`Filter`](crate::prelude::Filter)
//! - [`JsonCmp`](crate::prelude::JsonCmp)
//! - [`JsonFilter`](crate::prelude::JsonFilter)
//! - [`Query`](crate::prelude::Query)
//! - [`QueryBuilder`](crate::prelude::QueryBuilder)
//! - [`OrderDirection`](crate::prelude::OrderDirection)
//! - [`Select`](crate::prelude::Select)
//!
//! ### Table
//!
//! - [`ColumnDef`](crate::prelude::ColumnDef)
//! - [`ForeignKeyDef`](crate::prelude::ForeignKeyDef)
//! - [`InsertRecord`](crate::prelude::InsertRecord)
//! - [`TableColumns`](crate::prelude::TableColumns)
//! - [`TableError`](crate::prelude::TableError)
//! - [`TableRecord`](crate::prelude::TableRecord)
//! - [`UpdateRecord`](crate::prelude::UpdateRecord)
//! - [`ValuesSource`](crate::prelude::ValuesSource)
//!
//! ### Types
//!
//! - [`Blob`](crate::prelude::Blob)
//! - [`Boolean`](crate::prelude::Boolean)
//! - [`Date`](crate::prelude::Date)
//! - [`DateTime`](crate::prelude::DateTime)
//! - [`Decimal`](crate::prelude::Decimal)
//! - [`Int8`](crate::prelude::Int8)
//! - [`Int16`](crate::prelude::Int16)
//! - [`Int32`](crate::prelude::Int32)
//! - [`Int64`](crate::prelude::Int64)
//! - [`Json`](crate::prelude::Json)
//! - [`Nullable`](crate::prelude::Nullable)
//! - [`Principal`](crate::prelude::Principal)
//! - [`Text`](crate::prelude::Text)
//! - [`Uint8`](crate::prelude::Uint8)
//! - [`Uint16`](crate::prelude::Uint16)
//! - [`Uint32`](crate::prelude::Uint32)
//! - [`Uint64`](crate::prelude::Uint64)
//! - [`Uuid`](crate::prelude::Uuid)
//!
//! ### Value
//!
//! - [`Value`](crate::prelude::Value)
//!
//! ## Interact with an IC DBMS Canister
//!
//! ## Client
//!
//! All the client methods can be accessed through the [`Client`](crate::prelude::Client) trait.
//!
//! The crate provides an implementation of the client for IC DBMS Canister, called [`IcDbmsCanisterClient`](crate::prelude::IcDbmsCanisterClient),
//! which can be used on ic canisters.
//!
//! If you want to use the client in integration tests with `pocket-ic`, you can use the
//! [`IcDbmsPocketIcClient`](crate::prelude::IcDbmsPocketIcClient) implementation, but first you need to enable the `pocket-ic` feature.
//!
//! If you want to use the client from external systems (such as frontend applications, backend services, or CLI tools),
//! you can use the [`IcDbmsAgentClient`](crate::prelude::IcDbmsAgentClient) implementation, which requires the `ic-agent` feature.
//!
//! ## Usage
//!
//! ### Add the dependencies
//!
//! ```toml
//! [dependencies]
//! candid = "0.10"
//! ic-dbms-api = "0.1"
//! ic-dbms-client = "0.1"
//! serde = "1"
//! ```
//!
//! ### Implement the record types
//!
//! You can define your table as you did for the database, or use a common crate to share the types between the canisters.
//!
//! ```rust,ignore
//! use candid::{CandidType, Principal};
//! use ic_dbms_api::prelude::{Nullable, Query, Table, TableSchema, Text, Uint32, Uint64};
//! use ic_dbms_client::prelude::{Client as _, IcDbmsCanisterClient};
//! use serde::Deserialize;
//!
//! #[derive(Table, CandidType, Clone, Deserialize)]
//! #[table = "users"]
//! pub struct User {
//! #[primary_key]
//! id: Uint64,
//! name: Text,
//! email: Text,
//! age: Nullable<Uint32>,
//! }
//! ```
//!
//! ### Use the client
//!
//! ```rust,ignore
//! let principal = Principal::from_text("...")?;
//! let client = IcDbmsCanisterClient::new(principal);
//!
//! let alice = UserInsertRequest {
//! id: 1.into(),
//! name: "Alice".into(),
//! email: "alice@example.com".into(),
//! age: Nullable::Value(30.into()),
//! };
//!
//! client
//! .insert::<User>(User::table_name(), alice, None)
//! .await?;
//! ```
//!