Struct persy::Transaction
source · pub struct Transaction { /* private fields */ }
Expand description
Transaction container, it include all the changes done in a transaction.
Implementations§
source§impl Transaction
impl Transaction
sourcepub fn create_segment(
&mut self,
segment: &str
) -> Result<SegmentId, PE<CreateSegmentError>>
pub fn create_segment(
&mut self,
segment: &str
) -> Result<SegmentId, PE<CreateSegmentError>>
Create a new segment with the provided name
Example
let mut tx = persy.begin()?;
tx.create_segment("my_new_segment")?;
tx.prepare()?.commit()?;
sourcepub fn drop_segment(&mut self, segment: &str) -> Result<(), PE<DropSegmentError>>
pub fn drop_segment(&mut self, segment: &str) -> Result<(), PE<DropSegmentError>>
Drop a existing segment
Example
let mut tx = persy.begin()?;
tx.drop_segment("existing_segment_name")?;
tx.prepare()?.commit()?;
sourcepub fn exists_segment(&self, segment: &str) -> Result<bool, PE<GenericError>>
pub fn exists_segment(&self, segment: &str) -> Result<bool, PE<GenericError>>
Check if a segment already exist in the storage considering the transaction
Example
let mut tx = persy.begin()?;
tx.create_segment("my_new_segment")?;
assert!(tx.exists_segment("my_new_segment")?);
sourcepub fn solve_segment_id(
&self,
segment: impl ToSegmentId
) -> Result<SegmentId, PE<SegmentError>>
pub fn solve_segment_id(
&self,
segment: impl ToSegmentId
) -> Result<SegmentId, PE<SegmentError>>
Resolves the segment to a SegmentId, considering the transaction
Example
let mut tx = persy.begin()?;
tx.create_segment("my_new_segment")?;
let segment_id = tx.solve_segment_id("my_new_segment")?;
Examples found in repository?
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
pub fn read(&mut self, segment: impl ToSegmentId, id: &PersyId) -> Result<Option<Vec<u8>>, PE<ReadError>> {
let segment_id = self.solve_segment_id(segment).map_err(|PE::PE(e)| ReadError::from(e))?;
Ok(self.persy_impl.read_tx(tx_mut(&mut self.tx), segment_id, &id.0)?)
}
/// Scan for persistent and in transaction records
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// let mut count = 0;
/// for (id,content) in tx.scan("seg")? {
/// println!("record size:{}",content.len());
/// count+=1;
/// }
/// assert_eq!(count,1);
/// # Ok(())
/// # }
/// ```
pub fn scan(&mut self, segment: impl ToSegmentId) -> Result<TxSegmentIter, PE<SegmentError>> {
let segment_id = self.solve_segment_id(segment)?;
Ok(TxSegmentIter::new(
self.persy_impl.scan_tx(self.tx.as_mut().unwrap(), segment_id)?,
self,
))
}
/// Update the record content.
///
/// This updated content can be read only with the [`transaction read`] till the transaction is committed.
///
/// [`read`]:struct.Transaction.html#method.read
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// let new_data = vec![2;20];
/// tx.update("seg", &id, &new_data)?;
/// # tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn update(&mut self, segment: impl ToSegmentId, id: &PersyId, rec: &[u8]) -> Result<(), PE<UpdateError>> {
let segment_id = self
.solve_segment_id(segment)
.map_err(|e| PE::PE(UpdateError::from(e.error())))?;
Ok(self.persy_impl.update(tx_mut(&mut self.tx), segment_id, &id.0, rec)?)
}
/// Delete a record.
///
/// The record will result deleted only reading it with [`transaction read`] till the transaction is committed.
///
/// [`transaction read`]:struct.Persy.html#method.read
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// tx.delete("seg", &id)?;
/// # tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn delete(&mut self, segment: impl ToSegmentId, id: &PersyId) -> Result<(), PE<DeleteError>> {
let segment_id = self
.solve_segment_id(segment)
.map_err(|e| PE::PE(DeleteError::from(e.error())))?;
Ok(self.persy_impl.delete(tx_mut(&mut self.tx), segment_id, &id.0)?)
}
sourcepub fn solve_index_id(
&self,
index: impl ToIndexId
) -> Result<IndexId, PE<IndexError>>
pub fn solve_index_id(
&self,
index: impl ToIndexId
) -> Result<IndexId, PE<IndexError>>
Resolves the index name to a IndexId, considering the transaction, this has no public use as today, but may be used in future.
Example
let mut tx = persy.begin()?;
tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
let index_id = tx.solve_index_id("my_new_index")?;
Examples found in repository?
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
pub fn put<K, V>(&mut self, index_name: &str, k: K, v: V) -> Result<(), PE<IndexPutError>>
where
K: IndexType,
V: IndexType,
{
let index_id = self
.solve_index_id(index_name)
.map_err(|e| PE::PE(IndexPutError::from(e.error())))?;
Ok(self
.persy_impl
.put::<K::Wrapper, V::Wrapper>(tx_mut(&mut self.tx), index_id, k.wrap(), v.wrap())?)
}
/// Remove a key and optionally a specific value from an index following the value mode strategy.
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions, ValueMode};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// tx.put::<u8,u8>("my_new_index",10,10)?;
/// tx.remove::<u8,u8>("my_new_index",10,Some(10))?;
/// # tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn remove<K, V>(&mut self, index_name: &str, k: K, v: Option<V>) -> Result<(), PE<IndexOpsError>>
where
K: IndexType,
V: IndexType,
{
let index_id = self
.solve_index_id(index_name)
.map_err(|e| PE::PE(IndexOpsError::from(e.error())))?;
Ok(self.persy_impl.remove::<K::Wrapper, V::Wrapper>(
tx_mut(&mut self.tx),
index_id,
k.wrap(),
v.map(|rv| rv.wrap()),
)?)
}
/// Get a value or a group of values from a key considering changes in transaction.
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions, ValueMode};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// # let mut tx = persy.begin()?;
/// # tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// tx.put::<u8,u8>("my_new_index",10,10)?;
/// let values = tx.get::<u8,u8>("my_new_index",&10)?;
/// for value in values {
/// //...
/// }
/// # tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn get<K, V>(&mut self, index_name: &str, k: &K) -> Result<ValueIter<V>, PE<IndexChangeError>>
where
K: IndexType,
V: IndexType,
{
let index_id = self
.solve_index_id(index_name)
.map_err(|e| IndexChangeError::from(e.error()))?;
let entry: Option<Value<V::Wrapper>> =
self.persy_impl
.get_tx::<K::Wrapper, V::Wrapper>(tx_mut(&mut self.tx), index_id, &k.clone().wrap())?;
Ok(ValueIter::from(entry))
}
/// Get one value or none from a key considering changes in transaction.
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions, ValueMode};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// # let mut tx = persy.begin()?;
/// # tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// tx.put::<u8,u8>("my_new_index",10,10)?;
/// if let Some(value) = tx.one::<u8,u8>("my_new_index",&10)?{
/// //...
/// }
/// # tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn one<K, V>(&mut self, index_name: &str, k: &K) -> Result<Option<V>, PE<IndexChangeError>>
where
K: IndexType,
V: IndexType,
{
Ok(self.get(index_name, k)?.next())
}
/// Browse a range of keys and values from an index including the transaction changes
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions, ValueMode, TxIndexIter};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// tx.put::<u8,u8>("my_new_index",10,10)?;
/// {
/// let iter:TxIndexIter<u8,u8> = tx.range("my_new_index",10..12)?;
/// for (k,values) in iter {
/// for value in values {
/// //...
/// }
/// }
/// }
/// tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub fn range<'a, K, V, R>(
&'a mut self,
index_name: &str,
range: R,
) -> Result<TxIndexIter<'a, K, V>, PE<IndexOpsError>>
where
K: IndexType,
V: IndexType,
R: RangeBounds<K>,
{
let index_id = self
.solve_index_id(index_name)
.map_err(|e| IndexOpsError::from(e.error()))?;
let imp = self.persy_impl.clone();
let range = PersyImpl::map_index_range_bounds(range);
let tx_raw = imp.range_tx(self.tx_mut(), index_id, range)?;
Ok(TxIndexIter::new(tx_raw, self))
}
sourcepub fn insert(
&mut self,
segment: impl ToSegmentId,
rec: &[u8]
) -> Result<PersyId, PE<InsertError>>
pub fn insert(
&mut self,
segment: impl ToSegmentId,
rec: &[u8]
) -> Result<PersyId, PE<InsertError>>
Create a new record.
This function return an id that can be used by read
,
the record content can be read only with the transaction read
till the transaction is committed.
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
tx.insert("seg", &data)?;
tx.prepare()?.commit()?;
sourcepub fn read(
&mut self,
segment: impl ToSegmentId,
id: &PersyId
) -> Result<Option<Vec<u8>>, PE<ReadError>>
pub fn read(
&mut self,
segment: impl ToSegmentId,
id: &PersyId
) -> Result<Option<Vec<u8>>, PE<ReadError>>
Read the record content considering eventual in transaction changes.
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
let id = tx.insert("seg", &data)?;
let read = tx.read("seg", &id)?.expect("record exists");
assert_eq!(data,read);
sourcepub fn scan(
&mut self,
segment: impl ToSegmentId
) -> Result<TxSegmentIter<'_>, PE<SegmentError>>
pub fn scan(
&mut self,
segment: impl ToSegmentId
) -> Result<TxSegmentIter<'_>, PE<SegmentError>>
Scan for persistent and in transaction records
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
let id = tx.insert("seg", &data)?;
let mut count = 0;
for (id,content) in tx.scan("seg")? {
println!("record size:{}",content.len());
count+=1;
}
assert_eq!(count,1);
sourcepub fn update(
&mut self,
segment: impl ToSegmentId,
id: &PersyId,
rec: &[u8]
) -> Result<(), PE<UpdateError>>
pub fn update(
&mut self,
segment: impl ToSegmentId,
id: &PersyId,
rec: &[u8]
) -> Result<(), PE<UpdateError>>
Update the record content.
This updated content can be read only with the [transaction read
] till the transaction is committed.
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
let id = tx.insert("seg", &data)?;
let new_data = vec![2;20];
tx.update("seg", &id, &new_data)?;
sourcepub fn delete(
&mut self,
segment: impl ToSegmentId,
id: &PersyId
) -> Result<(), PE<DeleteError>>
pub fn delete(
&mut self,
segment: impl ToSegmentId,
id: &PersyId
) -> Result<(), PE<DeleteError>>
Delete a record.
The record will result deleted only reading it with transaction read
till the transaction is committed.
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
let id = tx.insert("seg", &data)?;
tx.delete("seg", &id)?;
sourcepub fn create_index<K, V>(
&mut self,
index_name: &str,
value_mode: ValueMode
) -> Result<(), PE<CreateIndexError>>where
K: IndexType,
V: IndexType,
pub fn create_index<K, V>(
&mut self,
index_name: &str,
value_mode: ValueMode
) -> Result<(), PE<CreateIndexError>>where
K: IndexType,
V: IndexType,
Create a new index with the name and the value management mode.
The create operation require two template arguments that are the types as keys and values of the index this have to match the following operation on the indexes.
Example
let mut tx = persy.begin()?;
tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
sourcepub fn drop_index(&mut self, index_name: &str) -> Result<(), PE<DropIndexError>>
pub fn drop_index(&mut self, index_name: &str) -> Result<(), PE<DropIndexError>>
sourcepub fn exists_index(&self, index_name: &str) -> Result<bool, PE<GenericError>>
pub fn exists_index(&self, index_name: &str) -> Result<bool, PE<GenericError>>
Check if a segment already exist in the storage considering the transaction
Example
let mut tx = persy.begin()?;
tx.create_index::<u8,u8>("my_new_index", ValueMode::Replace)?;
assert!(tx.exists_index("my_new_index")?);
sourcepub fn put<K, V>(
&mut self,
index_name: &str,
k: K,
v: V
) -> Result<(), PE<IndexPutError>>where
K: IndexType,
V: IndexType,
pub fn put<K, V>(
&mut self,
index_name: &str,
k: K,
v: V
) -> Result<(), PE<IndexPutError>>where
K: IndexType,
V: IndexType,
Put a key value in an index following the value mode strategy.
Example
let mut tx = persy.begin()?;
tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
tx.put::<u8,u8>("my_new_index",10,10)?;
tx.prepare()?.commit()?;
sourcepub fn remove<K, V>(
&mut self,
index_name: &str,
k: K,
v: Option<V>
) -> Result<(), PE<IndexOpsError>>where
K: IndexType,
V: IndexType,
pub fn remove<K, V>(
&mut self,
index_name: &str,
k: K,
v: Option<V>
) -> Result<(), PE<IndexOpsError>>where
K: IndexType,
V: IndexType,
Remove a key and optionally a specific value from an index following the value mode strategy.
Example
let mut tx = persy.begin()?;
tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
tx.put::<u8,u8>("my_new_index",10,10)?;
tx.remove::<u8,u8>("my_new_index",10,Some(10))?;
sourcepub fn get<K, V>(
&mut self,
index_name: &str,
k: &K
) -> Result<ValueIter<V>, PE<IndexChangeError>>where
K: IndexType,
V: IndexType,
pub fn get<K, V>(
&mut self,
index_name: &str,
k: &K
) -> Result<ValueIter<V>, PE<IndexChangeError>>where
K: IndexType,
V: IndexType,
Get a value or a group of values from a key considering changes in transaction.
Example
tx.put::<u8,u8>("my_new_index",10,10)?;
let values = tx.get::<u8,u8>("my_new_index",&10)?;
for value in values {
//...
}
sourcepub fn one<K, V>(
&mut self,
index_name: &str,
k: &K
) -> Result<Option<V>, PE<IndexChangeError>>where
K: IndexType,
V: IndexType,
pub fn one<K, V>(
&mut self,
index_name: &str,
k: &K
) -> Result<Option<V>, PE<IndexChangeError>>where
K: IndexType,
V: IndexType,
Get one value or none from a key considering changes in transaction.
Example
tx.put::<u8,u8>("my_new_index",10,10)?;
if let Some(value) = tx.one::<u8,u8>("my_new_index",&10)?{
//...
}
sourcepub fn range<'a, K, V, R>(
&'a mut self,
index_name: &str,
range: R
) -> Result<TxIndexIter<'a, K, V>, PE<IndexOpsError>>where
K: IndexType,
V: IndexType,
R: RangeBounds<K>,
pub fn range<'a, K, V, R>(
&'a mut self,
index_name: &str,
range: R
) -> Result<TxIndexIter<'a, K, V>, PE<IndexOpsError>>where
K: IndexType,
V: IndexType,
R: RangeBounds<K>,
Browse a range of keys and values from an index including the transaction changes
Example
let mut tx = persy.begin()?;
tx.put::<u8,u8>("my_new_index",10,10)?;
{
let iter:TxIndexIter<u8,u8> = tx.range("my_new_index",10..12)?;
for (k,values) in iter {
for value in values {
//...
}
}
}
tx.prepare()?.commit()?;
sourcepub fn rollback(self) -> Result<(), PE<GenericError>>
pub fn rollback(self) -> Result<(), PE<GenericError>>
Rollback a not yet prepared transaction.
All the resources used for eventual insert or update are released.
Example
let mut tx = persy.begin()?;
let data = vec![1;20];
tx.insert("seg", &data)?;
tx.rollback()?;
sourcepub fn prepare(self) -> Result<TransactionFinalize, PE<PrepareError>>
pub fn prepare(self) -> Result<TransactionFinalize, PE<PrepareError>>
Prepare to commit a transaction, when this method return all the validation checks are done and is guaranteed that the transaction can be committed successfully
it will lock all the records involved in the transaction
till a commit
or rollback
is called.
Example
let mut tx = persy.begin()?;
//Do what ever operations on the records
let data = vec![1;20];
tx.insert("seg", &data)?;
tx.prepare()?;
sourcepub fn list_segments(&self) -> Result<Vec<(String, SegmentId)>, GenericError>
pub fn list_segments(&self) -> Result<Vec<(String, SegmentId)>, GenericError>
List all the existing segments, considering all the changes in transaction.
Example
let mut tx = persy.begin()?;
tx.create_segment("seg")?;
let segments = tx.list_segments()?;
let names = segments.into_iter().map(|(name,_id)|name).collect::<Vec<String>>();
assert!(names.contains(&"seg".to_string()));
tx.prepare()?.commit()?;
sourcepub fn list_indexes(&self) -> Result<Vec<(String, IndexInfo)>, PE<GenericError>>
pub fn list_indexes(&self) -> Result<Vec<(String, IndexInfo)>, PE<GenericError>>
List all the existing indexes, considering changes in the transaction.
Example
let mut tx = persy.begin()?;
tx.create_index::<u8, u8>("idx", ValueMode::Replace)?;
let indexes = tx.list_indexes()?;
let names = indexes.into_iter().map(|(name,_id)|name).collect::<Vec<String>>();
assert!(names.contains(&"idx".to_string()));
tx.prepare()?.commit()?;