From 13cfee88844218fcd18033f50654ff5c55d072f2 Mon Sep 17 00:00:00 2001 From: Islam El-Ashi Date: Tue, 26 Sep 2023 14:09:03 +0300 Subject: [PATCH 1/4] docs: add schema upgrades tutorial --- README.md | 4 +++ docs/schema_upgrades.md | 66 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 docs/schema_upgrades.md diff --git a/README.md b/README.md index fff76635..ef8890b8 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ For more information about the philosophy behind the library, see [Roman's tutor - [Cell]: A serializable value - [MinHeap]: A priority queue. +## Tutorials + +[Schema Upgrades](./docs/schema-upgrades.md) + ## How it Works Stable structures are able to work directly in stable memory because each data structure manages diff --git a/docs/schema_upgrades.md b/docs/schema_upgrades.md new file mode 100644 index 00000000..12758e50 --- /dev/null +++ b/docs/schema_upgrades.md @@ -0,0 +1,66 @@ +# Schema Upgrades + +Stable structures store data directly in stable memory and do not require upgrade hooks. +Since these structures are designed to persist throughout the lifetime of the canister, it's nearly inevitable that developers would want to make modifications to the data's schema as the canister evolves. + +Let's say you are storing assets in your canister. The declaration of it can look something like this: + +```rust +#[derive(Serialize, Deserialize, CandidType)] +struct Asset { + // The contents of the asset. + contents: Vec, +} + +impl Storable for Asset { + fn to_bytes(&self) -> std::borrow::Cow<[u8]> { + let mut bytes = vec![]; + ciborium::ser::into_writer(&self, &mut bytes).unwrap(); + Cow::Owned(bytes) + } + + fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { + ciborium::de::from_reader(&*bytes).expect("deserialization must succeed.") + } + + const BOUND: Bound = Bound::Unbounded; +} +``` + +> **Note:** Stables structures do not enforce a specific data format. +It's up to the developer to use the data format that fits their use-case. +In this example, CBOR is used for encoding `Asset`. + + +## Adding an attribute + +Adding a new field can be as simple as adding the field, like this: + +```rust +#[derive(Serialize, Deserialize)] +struct Asset { + // The contents of the asset. + contents: Vec, + + // The timestamp the asset was created at. + #[serde(default)] + created_at: u64, +} +``` + +If the new attribute being added doesn't have a sensible default value, consider wrapping it in an `Option`: + +```rust +#[derive(Serialize, Deserialize, CandidType)] +struct Asset { + // The contents of the asset. + contents: Vec, + + // The timestamp the asset was created at. + #[serde(default)] + created_at: u64, + + // The username of the uploader. + uploaded_by: Option, +} +``` From e8e2939be674cead35e95fc0ea9659cc5d3bfc17 Mon Sep 17 00:00:00 2001 From: Islam El-Ashi Date: Tue, 26 Sep 2023 14:10:49 +0300 Subject: [PATCH 2/4] . --- docs/{schema_upgrades.md => schema-upgrades.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{schema_upgrades.md => schema-upgrades.md} (100%) diff --git a/docs/schema_upgrades.md b/docs/schema-upgrades.md similarity index 100% rename from docs/schema_upgrades.md rename to docs/schema-upgrades.md From 8417604a0ed8ae54a8d4dfcbd4996956b791cd75 Mon Sep 17 00:00:00 2001 From: Islam El-Ashi Date: Tue, 26 Sep 2023 15:00:00 +0300 Subject: [PATCH 3/4] chore: bump beta release version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2e401151..ca0bab96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ic-stable-structures" -version = "0.6.0-beta.1" +version = "0.6.0-beta.2" edition = "2021" description = "A collection of data structures for fearless canister upgrades." homepage = "https://docs.rs/ic-stable-structures" From 139183e0a0dcb473ec439812553db43041d26d9b Mon Sep 17 00:00:00 2001 From: Islam El-Ashi Date: Tue, 26 Sep 2023 15:00:39 +0300 Subject: [PATCH 4/4] . --- examples/Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 2c90b140..8c5151ad 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -285,7 +285,7 @@ dependencies = [ [[package]] name = "ic-stable-structures" -version = "0.6.0-beta.1" +version = "0.6.0-beta.2" [[package]] name = "ic0"