pub struct RwTransaction<'db> { /* private fields */ }
Expand description
Read-write transaction.
Implementations§
Source§impl<'db> RwTransaction<'db>
impl<'db> RwTransaction<'db>
Sourcepub fn get<'txn>(&'txn self) -> RwGet<'db, 'txn>
pub fn get<'txn>(&'txn self) -> RwGet<'db, 'txn>
Get a value from the database.
Same as RTransaction::get()
.
Sourcepub fn scan<'txn>(&'txn self) -> RwScan<'db, 'txn>
pub fn scan<'txn>(&'txn self) -> RwScan<'db, 'txn>
Get values from the database.
Same as RTransaction::scan()
.
Sourcepub fn len<'txn>(&'txn self) -> RwLen<'db, 'txn>
pub fn len<'txn>(&'txn self) -> RwLen<'db, 'txn>
Get the number of values in the database.
Same as RTransaction::len()
.
Sourcepub fn drain<'txn>(&'txn self) -> RwDrain<'db, 'txn>
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>
impl<'db, 'txn> RwTransaction<'db>
Sourcepub fn commit(self) -> Result<()>
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>
impl<'db, 'txn> RwTransaction<'db>
Sourcepub fn insert<T: Input>(&self, item: T) -> Result<()>
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(())
}
Sourcepub fn remove<T: Input>(&self, item: T) -> Result<T>
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(())
}
Sourcepub fn update<T: Input>(&self, old_item: T, updated_item: T) -> Result<()>
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()?;
// Remove a value
rw.update(Data { id: 1 }, Data { id: 2 })?;
// /!\ Don't forget to commit the transaction
rw.commit()?;
Ok(())
}
Sourcepub fn convert_all<OldType, NewType>(&self) -> Result<()>
pub fn convert_all<OldType, NewType>(&self) -> Result<()>
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(())
}
Sourcepub fn migrate<T: Input + Debug>(&self) -> Result<()>
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
andFrom<Data> for LegacyData
or implementTryFrom<LegacyData> for Data
andTryFrom<Data> for LegacyData
. - You must define all models (by calling
define
) before to callmigration
. - You must call use the most recent/bigger version as the target version when you call
migration
:migration::<Data>()
. That means you can’t callmigration::<LegacyData>()
becauseLegacyData
has version1
andData
has version2
.
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()
}