Struct persy::Transaction

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

Transaction container, it include all the changes done in a transaction.

Implementations§

Create a new segment with the provided name

Example
let mut tx = persy.begin()?;
tx.create_segment("my_new_segment")?;
tx.prepare()?.commit()?;

Drop a existing segment

Example
let mut tx = persy.begin()?;
tx.drop_segment("existing_segment_name")?;
tx.prepare()?.commit()?;

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")?);

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?
src/transaction.rs (line 193)
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)?)
    }

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?
src/transaction.rs (line 371)
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))
    }

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()?;

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);

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);

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)?;

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)?;

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)?;

Drop an existing index.

Example
let mut tx = persy.begin()?;
tx.drop_index("my_new_index")?;

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")?);

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()?;

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))?;

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 {
 //...
}
Examples found in repository?
src/transaction.rs (line 466)
461
462
463
464
465
466
467
    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())
    }

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)?{
 //...
}

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()?;

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()?;

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()?;

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()?;

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()?;

Prepare and Commit a transaction

Example
let mut tx = persy.begin()?;
//Do what ever operations on the records
let data = vec![1;20];
tx.insert("seg", &data)?;
tx.commit()?;

Trait Implementations§

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.