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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#![deny(missing_docs, unsafe_code)]
#![cfg_attr(not(feature = "doc"), forbid(unstable_features))]
#![cfg_attr(feature = "doc", feature(doc_cfg))]
//! A futures based crate for interacting with IndexedDB on browsers using webassembly.
//!
//! # Usage
//!
//! To use `idb`, you need to run following command from your project root:
//!
//! ```sh
//! cargo add idb
//! ```
//!
//! If you don't want to use `async`/`await` syntax, you can disable the `futures` feature using:
//!
//! ```sh
//! cargo add idb --no-default-features
//! ```
//!
//! After disabling the `futures` feature, you can use `on_success` and `on_error` methods on requests to attach
//! callbacks.
//!
//! ## Example
//!
//! To create a new database, you can use [`Factory::open`]:
//!
//! ```rust
//! use idb::{Database, DatabaseEvent, Error, Factory, IndexParams, KeyPath, ObjectStoreParams};
//!
//! async fn create_database() -> Result<Database, Error> {
//! // Get a factory instance from global scope
//! let factory = Factory::new()?;
//!
//! // Create an open request for the database
//! let mut open_request = factory.open("test", Some(1)).unwrap();
//!
//! // Add an upgrade handler for database
//! open_request.on_upgrade_needed(|event| {
//! // Get database instance from event
//! let database = event.database().unwrap();
//!
//! // Prepare object store params
//! let mut store_params = ObjectStoreParams::new();
//! store_params.auto_increment(true);
//! store_params.key_path(Some(KeyPath::new_single("id")));
//!
//! // Create object store
//! let store = database
//! .create_object_store("employees", store_params)
//! .unwrap();
//!
//! // Prepare index params
//! let mut index_params = IndexParams::new();
//! index_params.unique(true);
//!
//! // Create index on object store
//! store
//! .create_index("email", KeyPath::new_single("email"), Some(index_params))
//! .unwrap();
//! });
//!
//! // `await` open request
//! open_request.await
//! }
//! ```
//!
//! To add data to an object store, you can use [`ObjectStore::add`]:
//!
//! ```rust
//! use idb::{Database, Error, TransactionMode};
//! use serde::Serialize;
//! use serde_wasm_bindgen::Serializer;
//! use wasm_bindgen::JsValue;
//!
//! async fn add_data(database: &Database) -> Result<JsValue, Error> {
//! // Create a read-write transaction
//! let transaction = database.transaction(&["employees"], TransactionMode::ReadWrite)?;
//!
//! // Get the object store
//! let store = transaction.object_store("employees").unwrap();
//!
//! // Prepare data to add
//! let employee = serde_json::json!({
//! "name": "John Doe",
//! "email": "john@example.com",
//! });
//!
//! // Add data to object store
//! let id = store
//! .add(
//! &employee.serialize(&Serializer::json_compatible()).unwrap(),
//! None,
//! )
//! .unwrap()
//! .await?;
//!
//! // Commit the transaction
//! transaction.commit()?.await?;
//!
//! Ok(id)
//! }
//! ```
//!
//! To get data from an object store, you can use [`ObjectStore::get`]:
//!
//! ```rust
//! use idb::{Database, Error, TransactionMode};
//! use serde_json::Value;
//! use wasm_bindgen::JsValue;
//!
//! async fn get_data(database: &Database, id: JsValue) -> Result<Option<Value>, Error> {
//! // Create a read-only transaction
//! let transaction = database
//! .transaction(&["employees"], TransactionMode::ReadOnly)
//! .unwrap();
//!
//! // Get the object store
//! let store = transaction.object_store("employees").unwrap();
//!
//! // Get the stored data
//! let stored_employee: Option<JsValue> = store.get(id)?.await?;
//!
//! // Deserialize the stored data
//! let stored_employee: Option<Value> = stored_employee
//! .map(|stored_employee| serde_wasm_bindgen::from_value(stored_employee).unwrap());
//!
//! // Wait for the transaction to complete (alternatively, you can also commit the transaction)
//! transaction.await?;
//!
//! Ok(stored_employee)
//! }
//! ```
//!
//! For more examples on using other functionality, see the
//! [tests](https://github.com/devashishdxt/idb/tree/main/idb/tests) directory.
#[cfg(feature = "builder")]
#[cfg_attr(any(docsrs, feature = "doc"), doc(cfg(feature = "builder")))]
pub mod builder;
mod cursor;
mod database;
mod error;
pub mod event;
mod factory;
mod index;
mod key_range;
mod mappers;
mod object_store;
mod query;
pub mod request;
mod transaction;
mod utils;
pub use self::{
cursor::{Cursor, CursorDirection, KeyCursor},
database::Database,
error::Error,
event::{DatabaseEvent, Event, StoreEvent},
factory::Factory,
index::{Index, IndexParams},
key_range::KeyRange,
object_store::{KeyPath, ObjectStore, ObjectStoreParams},
query::Query,
request::Request,
transaction::{Transaction, TransactionMode},
};
#[cfg(feature = "futures")]
#[cfg_attr(any(docsrs, feature = "doc"), doc(cfg(feature = "futures")))]
pub use self::{
cursor::{ManagedCursor, ManagedKeyCursor},
transaction::{TransactionFuture, TransactionResult},
};