Struct native_db::transaction::RwTransaction

source ·
pub struct RwTransaction<'db> { /* private fields */ }
Expand description

Read-write transaction.

Implementations§

source§

impl<'db> RwTransaction<'db>

source

pub fn get<'txn>(&'txn self) -> RwGet<'db, 'txn>

Get a value from the database.

Same as RTransaction::get().

source

pub fn scan<'txn>(&'txn self) -> RwScan<'db, 'txn>

Get values from the database.

Same as RTransaction::scan().

source

pub fn len<'txn>(&'txn self) -> RwLen<'db, 'txn>

Get the number of values in the database.

Same as RTransaction::len().

source

pub fn drain<'txn>(&'txn self) -> RwDrain<'db, 'txn>

Get all values from the database.

Same as RTransaction::drain().

source§

impl<'db, 'txn> RwTransaction<'db>

source

pub fn commit(self) -> Result<()>

Commit the transaction. All changes will be applied to the database. If the commit fails, the transaction will be aborted. The database will be unchanged.

§Example
use native_db::*;

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    let db = builder.create_in_memory()?;
     
    // Open a read transaction
    let rw = db.rw_transaction()?;
    // Do some stuff..
    rw.commit()?;

    Ok(())
}
source§

impl<'db, 'txn> RwTransaction<'db>

source

pub fn insert<T: Input>(&self, item: T) -> Result<()>

Insert a value into the database.

§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 Data {
    #[primary_key]
    id: u64,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Data>()?;
    let db = builder.create_in_memory()?;
     
    // Open a read transaction
    let rw = db.rw_transaction()?;

    // Insert a value
    rw.insert(Data { id: 1 })?;

    // /!\ Don't forget to commit the transaction
    rw.commit()?;

    Ok(())
}
source

pub fn remove<T: Input>(&self, item: T) -> Result<T>

Remove a value from the database.

§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 Data {
    #[primary_key]
    id: u64,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Data>()?;
    let db = builder.create_in_memory()?;
     
    // Open a read transaction
    let rw = db.rw_transaction()?;

    // Remove a value
    let old_value = rw.remove(Data { id: 1 })?;

    // /!\ Don't forget to commit the transaction
    rw.commit()?;

    Ok(())
}
source

pub fn update<T: Input>(&self, old_item: T, updated_item: T) -> Result<()>

Update a value in the database.

That allow to update all keys (primary and secondary) of the value.

§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 Data {
    #[primary_key]
    id: u64,
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Data>()?;
    let db = builder.create_in_memory()?;
     
    // Open a read transaction
    let rw = db.rw_transaction()?;

    // Update a value
    rw.update(Data { id: 1 }, Data { id: 2 })?;

    // /!\ Don't forget to commit the transaction
    rw.commit()?;

    Ok(())
}
source

pub fn convert_all<OldType, NewType>(&self) -> Result<()>
where OldType: Input + Clone, NewType: Input + From<OldType>,

Convert all values from the database.

This is useful when you want to change the type/model of a value. You have to define From<SourceModel> for TargetModel to convert the value.

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

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

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

impl From<Dog> for Animal {
    fn from(dog: Dog) -> Self {
       Animal {
          name: dog.name,
          specie: "dog".to_string(),
        }
    }
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<Dog>()?;
    builder.define::<Animal>()?;
    let db = builder.create_in_memory()?;
     
    // Open a read transaction
    let rw = db.rw_transaction()?;

    // Convert all values from Dog to Animal
    rw.convert_all::<Dog, Animal>()?;

    // /!\ Don't forget to commit the transaction
    rw.commit()?;

    Ok(())
}
source

pub fn migrate<T: Input + Debug>(&self) -> Result<()>

Automatically migrate the data from the old model to the new model. No matter the state of the database, if all models remain defined in the application as they are, the data will be migrated to the most recent version automatically.

Native DB use the native_model identifier id to identify the model and version to identify the version of the model. We can define a model with the same identifier id but with a different version version.

In the example below we define one model with the identifier id=1 with tow versions version=1 and version=2.

  • You must link the previous version from the new one with from option like #[native_model(id=1, version=2, from=LegacyData)].
  • You must define the interoperability between the two versions with implement From<LegacyData> for Data and From<Data> for LegacyData or implement TryFrom<LegacyData> for Data and TryFrom<Data> for LegacyData.
  • You must define all models (by calling define) before to call migration.
  • You must call use the most recent/bigger version as the target version when you call migration: migration::<Data>(). That means you can’t call migration::<LegacyData>() because LegacyData has version 1 and Data has version 2.

After call migration::<Data>() all data of the model LegacyData will be migrated to the model Data.

Under the hood, when you call migration native_model is used to convert the data from the old model to the new model using the From or TryFrom implementation for each to target the version defined when you call migration::<LastVersion>().

It’s advisable to perform all migrations within a single transaction to ensure that all migrations are successfully completed.

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

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

impl From<Data> for LegacyData {
    fn from(data: Data) -> Self {
        LegacyData {
            id: data.id as u32,
        }
    }
}

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

impl From<LegacyData> for Data {
    fn from(legacy_data: LegacyData) -> Self {
        Data {
            id: legacy_data.id as u64,
        }
    }
}

fn main() -> Result<(), db_type::Error> {
    let mut builder = DatabaseBuilder::new();
    builder.define::<LegacyData>()?;
    builder.define::<Data>()?;
    let db = builder.create_in_memory()?;

    let rw = db.rw_transaction()?;
    rw.migrate::<Data>()?;
    // Other migrations if needed..
    rw.commit()
}

Auto Trait Implementations§

§

impl<'db> !Freeze for RwTransaction<'db>

§

impl<'db> !RefUnwindSafe for RwTransaction<'db>

§

impl<'db> Send for RwTransaction<'db>

§

impl<'db> !Sync for RwTransaction<'db>

§

impl<'db> Unpin for RwTransaction<'db>

§

impl<'db> !UnwindSafe for RwTransaction<'db>

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.