pub struct Database<T: Hash + Eq> {
pub label: String,
pub save_path: Option<PathBuf>,
pub strict_dupes: bool,
pub items: HashSet<T>,
}
Expand description
The primary database structure, allowing storage of a generic type with dumping/saving options avalible.
The generic type used should primarily be structures as they resemble a conventional database model and should implament hash::Hash and Eq for basic in-memory storage with Serialize and Deserialize being implamented for file operations involving the database (these are also required).
Fields
label: String
Friendly name for the database, preferibly in slug-form-like-this
as
this is the fallback path
This is used when dumping the database without a Database::save_path being defined and a friendly way to order a database
save_path: Option<PathBuf>
The overwrite path to save the database as, this is recommended otherwise
it will end up as ./Hello\ There.gddb
if Database::label is “Hello
There”
Primarily used inside of Database::dump_db.
strict_dupes: bool
If the database should return an error if it tries to insert where an
identical item already is. Setting this as false
doesn’t allow
duplicates, it just doesn’t flag an error.
items: HashSet<T>
In-memory HashSet of all items
Implementations
sourceimpl<Record: Hash + Eq + Serialize + DeserializeOwned> Database<Record>
impl<Record: Hash + Eq + Serialize + DeserializeOwned> Database<Record>
sourcepub fn new(
label: impl Into<String>,
save_path: impl Into<Option<PathBuf>>,
strict_dupes: bool
) -> Self
pub fn new(
label: impl Into<String>,
save_path: impl Into<Option<PathBuf>>,
strict_dupes: bool
) -> Self
Creates a new database instance from given parameters.
- To add a first item, use Database::create.
- If you’d like to load a dumped database, use Database::from
sourcepub fn from(path: impl Into<PathBuf>) -> Result<Self, DatabaseError>
pub fn from(path: impl Into<PathBuf>) -> Result<Self, DatabaseError>
Creates a database from a .gddb
file.
This retrives a dump file (saved database) from the path given and loads it as the Database structure.
Examples
use gddb::Database;
use serde::{Serialize, Deserialize};
use std::path::PathBuf;
/// Makes a small testing database.
fn make_db() {
let mut test_db: Database<Record> = Database::new("test", None, false);
test_db.create(Record::new("Test".into()));
test_db.dump_db();
}
/// Get `test_db` defined in [make_db] and test.
fn main() {
make_db();
let db = Database::from(
PathBuf::from("test.gddb")
).unwrap();
assert_eq!(
db.len(),
1
); // Check that the database still has added [ExampleStruct].
}
sourcepub fn create(&mut self, item: Record) -> Result<(), DatabaseError>
pub fn create(&mut self, item: Record) -> Result<(), DatabaseError>
Adds a new item to the in-memory database.
If this is the first item added to the database, please ensure it’s the only type you’d like to add. Due to generics, the first item you add will be set as the type to use (unless removed).
sourcepub fn update(
&mut self,
item: &Record,
new: Record
) -> Result<(), DatabaseError>
pub fn update(
&mut self,
item: &Record,
new: Record
) -> Result<(), DatabaseError>
Replaces an item inside of the database with another item, used for updating/replacing items easily.
Database::update can be used in conjunction to find and replace values individually if needed.
sourcepub fn auto_from(
path: impl Into<PathBuf>,
strict_dupes: bool
) -> Result<Self, DatabaseError>
pub fn auto_from(
path: impl Into<PathBuf>,
strict_dupes: bool
) -> Result<Self, DatabaseError>
Loads database from existant path or creates a new one if it doesn’t already exist.
This is the recommended way to use gddb if you are wanting to easily
setup an entire database instance in a short, consise manner. Similar to
Database::new and Database::from, this function will also have to be
given a strict type argument and you will still have to provide script_dupes
even if the database is likely to load an existing one.
This function does make some assumptions about the database name and uses
the 2nd to last part before a .
. This means that x.y.z
will have the
name of y
, not x
so therefore it is recommended to have a database
path with x.gddb
or x.db
only.
Examples
use gddb::*;
use std::path::PathBuf;
use serde::{Serialize, Deserialize};
fn main() {
let dummy_db: Database<Record> = Database::new("cool", None, false); // create demo db for `db_from`
let db_from_path = PathBuf::from("cool.gddb");
let db_from: Database<Record> = Database::auto_from(db_from_path, false).unwrap(); // automatically load it
let db_new_path = PathBuf::from("xyz.gddb");
let db_new: Database<Record> = Database::auto_from(db_new_path, false).unwrap(); // automatically create new as "xyz" doesn't exist
}
sourcepub fn destroy(&mut self, item: &Record) -> Result<(), DatabaseError>
pub fn destroy(&mut self, item: &Record) -> Result<(), DatabaseError>
Removes an item from the database.
See Database::update if you’d like to update/replace an item easily, rather than individually deleting and adding.
Errors
Will return DatabaseError::ItemNotFound if the item that is attempting to be deleted was not found.
sourcepub fn dump_db(&self) -> Result<(), DatabaseError>
pub fn dump_db(&self) -> Result<(), DatabaseError>
Dumps/saves database to a binary file.
Saving path methods
The database will usually save as \[label\].gddb
where \[label\]
is the defined Database::label (path is reletive to where gddb was
executed).
You can also overwrite this behaviour by defining a Database::save_path when generating the database inside of Database::new.
sourcepub fn find<Q: RecordCheck, V: Fn(&Record) -> &Q>(
&self,
value: V,
query: Q
) -> Result<&Record, DatabaseError>
pub fn find<Q: RecordCheck, V: Fn(&Record) -> &Q>(
&self,
value: V,
query: Q
) -> Result<&Record, DatabaseError>
Query the database for a specific item.
Syntax
self.find(|[p]| [p].[field], [query]);
[p]
The closure (Will be whatever the database currently is saving as a schema).[field]
The exact field ofp
. If the database doesn’t contain structures, don’t add the.[field]
.[query]
Item to query for. This is a generic and can be of any reasonable type.
Examples
use serde::{Serialize, Deserialize};
use gddb::Database;
#[derive(Debug, Eq, PartialEq, Hash, Serialize, Deserialize, Clone)]
struct ExampleStruct {
my_age: i32
}
fn main() {
let my_struct = ExampleStruct { my_age: 329 };
let mut my_db = Database::new("query_test", None, false);
my_db.create(my_struct.clone());
let results = my_db.find(|s: &ExampleStruct| &s.my_age, 329);
assert_eq!(results.unwrap(), &my_struct);
}
sourcepub fn query<Q: PartialEq, V: Fn(&Record) -> &Q>(
&self,
value: V,
query: Q
) -> Result<Vec<&Record>, DatabaseError>
pub fn query<Q: PartialEq, V: Fn(&Record) -> &Q>(
&self,
value: V,
query: Q
) -> Result<Vec<&Record>, DatabaseError>
Query the database for all matching items.
Syntax
self.query(|[p]| [p].[field], [query]);
[p]
The closure (Will be whatever the database currently is saving as a schema).[field]
The exact field ofp
. If the database doesn’t contain structures, don’t add the.[field]
.[query]
Item to query for. This is a generic and can be of any reasonable type.
Examples
use serde::{Serialize, Deserialize};
use gddb::Database;
#[derive(Debug, Eq, PartialEq, Hash, Serialize, Deserialize, Clone)]
struct ExampleStruct {
uuid: String,
age: i32,
}
fn main() {
let mut my_db = Database::new("query_test", None, false);
my_db.create(ExampleStruct { uuid: "test1".into(), age: 20 });
my_db.create(ExampleStruct { uuid: "test2".into(), age: 20 });
my_db.create(ExampleStruct { uuid: "test3".into(), age: 18 });
let results = my_db.query(|s: &ExampleStruct| &s.age, 20);
assert_eq!(results.unwrap().len(), 2);
}
sourcepub fn contains(&self, query: &Record) -> bool
pub fn contains(&self, query: &Record) -> bool
Searches the database for a specific value. If it does not exist, this method will return DatabaseError::ItemNotFound.
This is a wrapper around HashSet::contains.
Examples
use gddb::Database;
use serde::{Serialize, Deserialize};
#[derive(Hash, Eq, PartialEq, Serialize, Deserialize, Copy, Clone)]
struct ExampleStruct {
item: i32
}
fn main() {
let exp_struct = ExampleStruct { item: 4942 };
let mut db = Database::new("Contains example", None, false);
db.create(exp_struct.clone());
assert_eq!(db.contains(&exp_struct), true);
}
sourcepub fn len(&self) -> i32
pub fn len(&self) -> i32
Returns the number of database entries method will return i32.
Examples
use gddb::Database;
use serde::{Serialize, Deserialize};
#[derive(Hash, Eq, PartialEq, Serialize, Deserialize, Copy, Clone)]
struct ExampleStruct {
item: i32
}
fn main() {
let exp_struct = ExampleStruct { item: 4942 };
let mut db = Database::new("Contains example", None, false);
db.create(exp_struct.clone());
assert_eq!(db.len(), 1);
}
Trait Implementations
sourceimpl<'de, T: Hash + Eq> Deserialize<'de> for Database<T> where
T: Deserialize<'de>,
impl<'de, T: Hash + Eq> Deserialize<'de> for Database<T> where
T: Deserialize<'de>,
sourcefn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl<T: Eq + Hash + Eq> Eq for Database<T>
impl<T: Hash + Eq> StructuralEq for Database<T>
impl<T: Hash + Eq> StructuralPartialEq for Database<T>
Auto Trait Implementations
impl<T> RefUnwindSafe for Database<T> where
T: RefUnwindSafe,
impl<T> Send for Database<T> where
T: Send,
impl<T> Sync for Database<T> where
T: Sync,
impl<T> Unpin for Database<T> where
T: Unpin,
impl<T> UnwindSafe for Database<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<Q, K> Equivalent<K> for Q where
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Q where
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
sourcefn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to key
and return true
if they are equal.
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more