-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add builders (for convenience) for building database (#21)
* Add builders (for convenience) for building database * Don't include doc feature in CI
- Loading branch information
1 parent
ea37af7
commit c8c7605
Showing
16 changed files
with
324 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "idb" | ||
version = "0.6.0" | ||
version = "0.6.1" | ||
authors = ["Devashish Dixit <[email protected]>"] | ||
license = "MIT/Apache-2.0" | ||
description = "A futures based crate for interacting with IndexedDB on browsers using webassembly" | ||
|
@@ -16,6 +16,7 @@ edition = "2021" | |
[features] | ||
default = ["futures"] | ||
doc = [] | ||
builder = ["futures"] | ||
futures = ["tokio"] | ||
|
||
[dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
use std::collections::HashSet; | ||
|
||
use crate::{Database, DatabaseEvent, Error, Event, Factory}; | ||
|
||
use super::ObjectStoreBuilder; | ||
|
||
/// Builder for databases. | ||
#[derive(Debug)] | ||
pub struct DatabaseBuilder { | ||
name: String, | ||
version: Option<u32>, | ||
object_stores: Vec<ObjectStoreBuilder>, | ||
} | ||
|
||
impl DatabaseBuilder { | ||
/// Creates a new instance of [`DatabaseBuilder`]. | ||
pub fn new(name: &str) -> Self { | ||
Self { | ||
name: name.to_owned(), | ||
version: None, | ||
object_stores: Vec::new(), | ||
} | ||
} | ||
|
||
/// Sets the version of the database. | ||
pub fn version(mut self, version: u32) -> Self { | ||
self.version = Some(version); | ||
self | ||
} | ||
|
||
/// Adds an object store. | ||
pub fn add_object_store(mut self, object_store: ObjectStoreBuilder) -> Self { | ||
self.object_stores.push(object_store); | ||
self | ||
} | ||
|
||
/// Builds the database. | ||
pub async fn build(self) -> Result<Database, Error> { | ||
let factory = Factory::new()?; | ||
let mut request = factory.open(&self.name, self.version)?; | ||
|
||
request.on_upgrade_needed(move |event| { | ||
let request = event.target().expect("open database request"); | ||
|
||
let mut store_names: HashSet<_> = self | ||
.object_stores | ||
.iter() | ||
.map(|store| store.name().to_owned()) | ||
.collect(); | ||
|
||
let database = event.database().expect("database"); | ||
|
||
for object_store in self.object_stores { | ||
object_store | ||
.apply(&database, &request) | ||
.expect("object store creation"); | ||
} | ||
|
||
let db_store_names = database.store_names(); | ||
let mut stores_to_remove = Vec::new(); | ||
|
||
for db_store_name in db_store_names { | ||
if !store_names.contains(&db_store_name) { | ||
store_names.remove(&db_store_name); | ||
} else { | ||
stores_to_remove.push(db_store_name); | ||
} | ||
} | ||
|
||
for store_name in stores_to_remove { | ||
database | ||
.delete_object_store(&store_name) | ||
.expect("object store deletion"); | ||
} | ||
}); | ||
|
||
let mut database = request.await?; | ||
|
||
database.on_version_change(|event| { | ||
let database = event.database().expect("database"); | ||
database.close(); | ||
}); | ||
|
||
Ok(database) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use crate::{Error, IndexParams, KeyPath, ObjectStore}; | ||
|
||
/// Builder for object store indexes. | ||
#[derive(Debug)] | ||
pub struct IndexBuilder { | ||
name: String, | ||
key_path: KeyPath, | ||
unique: Option<bool>, | ||
multi_entry: Option<bool>, | ||
} | ||
|
||
impl IndexBuilder { | ||
/// Creates a new instance of [`IndexBuilder`]. | ||
pub fn new(name: String, key_path: KeyPath) -> Self { | ||
Self { | ||
name, | ||
key_path, | ||
unique: None, | ||
multi_entry: None, | ||
} | ||
} | ||
|
||
/// Returns the name of the index. | ||
pub fn name(&self) -> &str { | ||
&self.name | ||
} | ||
|
||
/// Sets the `unique` flag. | ||
pub fn unique(mut self, unique: bool) -> Self { | ||
self.unique = Some(unique); | ||
self | ||
} | ||
|
||
/// Sets the `multi_entry` flag. | ||
pub fn multi_entry(mut self, multi_entry: bool) -> Self { | ||
self.multi_entry = Some(multi_entry); | ||
self | ||
} | ||
|
||
/// Applies the index to the given object store. | ||
pub(crate) fn apply(self, object_store: &ObjectStore) -> Result<(), Error> { | ||
let mut params = IndexParams::new(); | ||
|
||
if let Some(unique) = self.unique { | ||
params.unique(unique); | ||
} | ||
|
||
if let Some(multi_entry) = self.multi_entry { | ||
params.multi_entry(multi_entry); | ||
} | ||
|
||
object_store.create_index(&self.name, self.key_path, Some(params))?; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
//! Contains the builder for the database. | ||
mod database_builder; | ||
mod index; | ||
mod object_store; | ||
|
||
pub use self::{ | ||
database_builder::DatabaseBuilder, index::IndexBuilder, object_store::ObjectStoreBuilder, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
use std::collections::HashSet; | ||
|
||
use crate::{request::OpenDatabaseRequest, Database, Error, KeyPath, ObjectStoreParams, Request}; | ||
|
||
use super::IndexBuilder; | ||
|
||
/// Builder for object stores. | ||
#[derive(Debug)] | ||
pub struct ObjectStoreBuilder { | ||
name: String, | ||
auto_increment: Option<bool>, | ||
key_path: Option<KeyPath>, | ||
indexes: Vec<IndexBuilder>, | ||
} | ||
|
||
impl ObjectStoreBuilder { | ||
/// Creates a new instance of [`ObjectStoreBuilder`]. | ||
pub fn new(name: &str) -> Self { | ||
Self { | ||
name: name.to_owned(), | ||
auto_increment: None, | ||
key_path: None, | ||
indexes: Vec::new(), | ||
} | ||
} | ||
|
||
/// Returns the name of the object store. | ||
pub fn name(&self) -> &str { | ||
&self.name | ||
} | ||
|
||
/// Sets the `auto_increment` flag. | ||
pub fn auto_increment(mut self, auto_increment: bool) -> Self { | ||
self.auto_increment = Some(auto_increment); | ||
self | ||
} | ||
|
||
/// Sets the key path. | ||
pub fn key_path(mut self, key_path: Option<KeyPath>) -> Self { | ||
self.key_path = key_path; | ||
self | ||
} | ||
|
||
/// Adds an index. | ||
pub fn add_index(mut self, index: IndexBuilder) -> Self { | ||
self.indexes.push(index); | ||
self | ||
} | ||
|
||
pub(crate) fn apply( | ||
self, | ||
database: &Database, | ||
request: &OpenDatabaseRequest, | ||
) -> Result<(), Error> { | ||
let mut index_names: HashSet<_> = self | ||
.indexes | ||
.iter() | ||
.map(|index| index.name().to_owned()) | ||
.collect(); | ||
|
||
let object_store = if database.store_names().contains(&self.name) { | ||
let transaction = request | ||
.transaction() | ||
.ok_or_else(|| Error::TransactionNotFound)?; | ||
|
||
transaction.object_store(&self.name) | ||
} else { | ||
let mut params = ObjectStoreParams::new(); | ||
|
||
if let Some(auto_increment) = self.auto_increment { | ||
params.auto_increment(auto_increment); | ||
} | ||
|
||
if let Some(key_path) = self.key_path { | ||
params.key_path(Some(key_path)); | ||
} | ||
|
||
database.create_object_store(&self.name, params) | ||
}?; | ||
|
||
for index in self.indexes { | ||
index.apply(&object_store)?; | ||
} | ||
|
||
let db_index_names = object_store.index_names(); | ||
let mut indexes_to_remove = Vec::new(); | ||
|
||
for db_index_name in db_index_names { | ||
if index_names.contains(db_index_name.as_str()) { | ||
index_names.remove(db_index_name.as_str()); | ||
} else { | ||
indexes_to_remove.push(db_index_name); | ||
} | ||
} | ||
|
||
for index_name in indexes_to_remove { | ||
object_store.delete_index(&index_name)?; | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
mod cursor_direction; | ||
mod key_cursor; | ||
#[cfg(feature = "futures")] | ||
mod managed_key_cursor; | ||
#[cfg(feature = "futures")] | ||
mod managed_value_cursor; | ||
mod value_cursor; | ||
|
||
pub use self::{ | ||
cursor_direction::CursorDirection, key_cursor::KeyCursor, managed_key_cursor::ManagedKeyCursor, | ||
managed_value_cursor::ManagedCursor, value_cursor::Cursor, | ||
}; | ||
pub use self::{cursor_direction::CursorDirection, key_cursor::KeyCursor, value_cursor::Cursor}; | ||
#[cfg(feature = "futures")] | ||
pub use self::{managed_key_cursor::ManagedKeyCursor, managed_value_cursor::ManagedCursor}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.