Struct native_db::DatabaseBuilder

source ·
pub struct DatabaseBuilder { /* private fields */ }
Expand description

Builder that allows you to create a Database instance via create or open etc. and define models.

Implementations§

source§

impl DatabaseBuilder

source

pub fn new() -> Self

source

pub fn set_cache_size(&mut self, bytes: usize) -> &mut Self

source

pub fn create(&self, path: impl AsRef<Path>) -> Result<Database<'_>>

Creates a new Db instance using the given path.

Similar to redb::Builder.create(…)

source

pub fn open(&self, path: impl AsRef<Path>) -> Result<Database<'_>>

Similar to redb::Builder::open(…) But it also upgrades the database if needed if

source

pub fn create_in_memory(&self) -> Result<Database<'_>>

Creates a new Database instance in memory.

source

pub fn define<T: Input>(&mut self) -> Result<()>

Defines a table using the given model.

Native DB depends of native_model to define the model. And native_model by default uses serde to serialize and deserialize the data but you can use any other serialization library see the documentation of native_model for more information. So in the example below we import serde and we use the Serialize and Deserialize traits.

§Primary key

The primary key is strict, you must:

  • define it.
  • define only one.

If the primary key is not defined, the compiler will return an error Primary key is not set.

You can define with two ways:

  • #[primary_key] on the field
  • #[native_db(primary_key(<method_name>))] on any type enum, struct, tuple struct or unit struct.

The primary key is unique, so you can’t have two instances of the model with the same primary key saved in the database.

§Define a simple model with a primary key
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db]
struct Data {
    #[primary_key]
    id: u64,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Data>()
}
§Define a model with a method as primary key
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db(
    primary_key(custom_id)
)]
struct Data(u64);

impl Data {
  fn custom_id(&self) -> u32 {
    (self.0 + 1) as u32
  }
}
§Secondary key

The secondary key is flexible, you can:

  • define it or not.
  • define one or more.

You can define with two ways:

  • #[secondary_key] on the field
  • #[native_db(secondary_key(<method_name>, <options>))] on any type enum, struct, tuple struct or unit struct.

The secondary key can have two options:

§Define a model with a secondary key
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db]
struct Data {
    #[primary_key]
    id: u64,
    #[secondary_key]
    name: String,
}
§Define a model wit a secondary key optional and unique
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db]
struct Data {
    #[primary_key]
    id: u64,
    #[secondary_key(unique, optional)]
    name: Option<String>,
}
  • Note: the secondary key can be unique or optional as well.
§Unique

This means that each instance of the model must have a unique value for the secondary key. If the value is not unique, the insert method will return an error.

§Optional

This means that an instance of the model can have a value for the secondary key or not. Whenoptional is set the value must be an Option. if the value is not an Option the compiler will return an error error[E0282]: type annotations needed: cannot infer type.

Under the hood, the secondary key is stored in a separate redb table. So if the secondary key is optional, the value will be stored in the table only if the value is not None.

§Define a model with a secondary key and a custom secondary key optional
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db(
    secondary_key(custom_name, optional)
)]
struct Data {
    #[primary_key]
    id: u64,
    #[secondary_key]
    name: String,
    flag: bool,
}

impl Data {
    fn custom_name(&self) -> Option<String> {
        if self.flag {
            Some(self.name.clone().to_uppercase())
        } else {
            None
        }
    }
}
§Define multiple models

To define multiple models, you must use different id for each model. If you use the same id for two models, the program will panic with the message The table <table_name> has the same native model version as the table <table_name> and it's not allowed.

Example:

use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db]
struct Animal {
    #[primary_key]
    name: String,
}

#[derive(Serialize, Deserialize)]
#[native_model(id=2, version=1)]
#[native_db]
struct Vegetable {
    #[primary_key]
    name: String,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Animal>()?;
    builder.define::<Vegetable>()
}

Trait Implementations§

source§

impl Debug for DatabaseBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.