1use std::marker::PhantomData;
17
18use crate::{
19 AsColumnFamilyRef, DBIteratorWithThreadMode, DBPinnableSlice, DBRawIteratorWithThreadMode,
20 Direction, Error, IteratorMode, ReadOptions, SnapshotWithThreadMode, WriteBatchWithIndex,
21 WriteBatchWithTransaction,
22 db::{DBAccess, convert_values},
23 ffi,
24};
25use libc::{c_char, c_void, size_t};
26
27thread_local! { static DEFAULT_READ_OPTS: ReadOptions = ReadOptions::default(); }
34
35pub struct Transaction<'db, DB> {
65 pub(crate) inner: *mut ffi::rocksdb_transaction_t,
66 pub(crate) _marker: PhantomData<&'db DB>,
67}
68
69unsafe impl<DB> Send for Transaction<'_, DB> {}
70
71impl<DB> DBAccess for Transaction<'_, DB> {
72 unsafe fn create_snapshot(&self) -> *const ffi::rocksdb_snapshot_t {
73 unsafe { ffi::rocksdb_transaction_get_snapshot(self.inner) }
74 }
75
76 unsafe fn release_snapshot(&self, snapshot: *const ffi::rocksdb_snapshot_t) {
77 unsafe {
78 ffi::rocksdb_free(snapshot as *mut c_void);
79 }
80 }
81
82 unsafe fn create_iterator(&self, readopts: &ReadOptions) -> *mut ffi::rocksdb_iterator_t {
83 unsafe { ffi::rocksdb_transaction_create_iterator(self.inner, readopts.inner) }
84 }
85
86 unsafe fn create_iterator_cf(
87 &self,
88 cf_handle: *mut ffi::rocksdb_column_family_handle_t,
89 readopts: &ReadOptions,
90 ) -> *mut ffi::rocksdb_iterator_t {
91 unsafe {
92 ffi::rocksdb_transaction_create_iterator_cf(self.inner, readopts.inner, cf_handle)
93 }
94 }
95
96 fn get_opt<K: AsRef<[u8]>>(
97 &self,
98 key: K,
99 readopts: &ReadOptions,
100 ) -> Result<Option<Vec<u8>>, Error> {
101 self.get_opt(key, readopts)
102 }
103
104 fn get_cf_opt<K: AsRef<[u8]>>(
105 &self,
106 cf: &impl AsColumnFamilyRef,
107 key: K,
108 readopts: &ReadOptions,
109 ) -> Result<Option<Vec<u8>>, Error> {
110 self.get_cf_opt(cf, key, readopts)
111 }
112
113 fn get_pinned_opt<K: AsRef<[u8]>>(
114 &'_ self,
115 key: K,
116 readopts: &ReadOptions,
117 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
118 self.get_pinned_opt(key, readopts)
119 }
120
121 fn get_pinned_cf_opt<K: AsRef<[u8]>>(
122 &'_ self,
123 cf: &impl AsColumnFamilyRef,
124 key: K,
125 readopts: &ReadOptions,
126 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
127 self.get_pinned_cf_opt(cf, key, readopts)
128 }
129
130 fn multi_get_opt<K, I>(
131 &self,
132 keys: I,
133 readopts: &ReadOptions,
134 ) -> Vec<Result<Option<Vec<u8>>, Error>>
135 where
136 K: AsRef<[u8]>,
137 I: IntoIterator<Item = K>,
138 {
139 self.multi_get_opt(keys, readopts)
140 }
141
142 fn multi_get_cf_opt<'b, K, I, W>(
143 &self,
144 keys_cf: I,
145 readopts: &ReadOptions,
146 ) -> Vec<Result<Option<Vec<u8>>, Error>>
147 where
148 K: AsRef<[u8]>,
149 I: IntoIterator<Item = (&'b W, K)>,
150 W: AsColumnFamilyRef + 'b,
151 {
152 self.multi_get_cf_opt(keys_cf, readopts)
153 }
154}
155
156impl<DB> Transaction<'_, DB> {
157 pub fn commit(self) -> Result<(), Error> {
179 unsafe {
180 ffi_try!(ffi::rocksdb_transaction_commit(self.inner));
181 }
182 Ok(())
183 }
184
185 pub fn set_name(&self, name: &[u8]) -> Result<(), Error> {
186 let ptr = name.as_ptr();
187 let len = name.len();
188 unsafe {
189 ffi_try!(ffi::rocksdb_transaction_set_name(
190 self.inner, ptr as _, len as _
191 ));
192 }
193
194 Ok(())
195 }
196
197 pub fn get_name(&self) -> Option<Vec<u8>> {
198 unsafe {
199 let mut name_len = 0;
200 let name = ffi::rocksdb_transaction_get_name(self.inner, &raw mut name_len);
201 if name.is_null() {
202 None
203 } else {
204 let mut vec = vec![0; name_len];
205 std::ptr::copy_nonoverlapping(name.cast::<u8>(), vec.as_mut_ptr(), name_len);
206 ffi::rocksdb_free(name as *mut c_void);
207 Some(vec)
208 }
209 }
210 }
211
212 pub fn prepare(&self) -> Result<(), Error> {
213 unsafe {
214 ffi_try!(ffi::rocksdb_transaction_prepare(self.inner));
215 }
216 Ok(())
217 }
218
219 pub fn snapshot(&'_ self) -> SnapshotWithThreadMode<'_, Self> {
224 SnapshotWithThreadMode::new(self)
225 }
226
227 pub fn rollback(&self) -> Result<(), Error> {
229 unsafe {
230 ffi_try!(ffi::rocksdb_transaction_rollback(self.inner));
231 Ok(())
232 }
233 }
234
235 pub fn set_savepoint(&self) {
240 unsafe {
241 ffi::rocksdb_transaction_set_savepoint(self.inner);
242 }
243 }
244
245 pub fn rollback_to_savepoint(&self) -> Result<(), Error> {
252 unsafe {
253 ffi_try!(ffi::rocksdb_transaction_rollback_to_savepoint(self.inner));
254 Ok(())
255 }
256 }
257
258 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
264 DEFAULT_READ_OPTS.with(|opts| self.get_opt(key, opts))
265 }
266
267 pub fn get_pinned<K: AsRef<[u8]>>(
268 &'_ self,
269 key: K,
270 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
271 DEFAULT_READ_OPTS.with(|opts| self.get_pinned_opt(key, opts))
272 }
273
274 pub fn get_cf<K: AsRef<[u8]>>(
280 &self,
281 cf: &impl AsColumnFamilyRef,
282 key: K,
283 ) -> Result<Option<Vec<u8>>, Error> {
284 DEFAULT_READ_OPTS.with(|opts| self.get_cf_opt(cf, key, opts))
285 }
286
287 pub fn get_pinned_cf<K: AsRef<[u8]>>(
288 &'_ self,
289 cf: &impl AsColumnFamilyRef,
290 key: K,
291 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
292 DEFAULT_READ_OPTS.with(|opts| self.get_pinned_cf_opt(cf, key, opts))
293 }
294
295 pub fn get_for_update<K: AsRef<[u8]>>(
304 &self,
305 key: K,
306 exclusive: bool,
307 ) -> Result<Option<Vec<u8>>, Error> {
308 DEFAULT_READ_OPTS.with(|opts| self.get_for_update_opt(key, exclusive, opts))
309 }
310
311 pub fn get_pinned_for_update<K: AsRef<[u8]>>(
312 &'_ self,
313 key: K,
314 exclusive: bool,
315 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
316 DEFAULT_READ_OPTS.with(|opts| self.get_pinned_for_update_opt(key, exclusive, opts))
317 }
318
319 pub fn get_for_update_cf<K: AsRef<[u8]>>(
328 &self,
329 cf: &impl AsColumnFamilyRef,
330 key: K,
331 exclusive: bool,
332 ) -> Result<Option<Vec<u8>>, Error> {
333 DEFAULT_READ_OPTS.with(|opts| self.get_for_update_cf_opt(cf, key, exclusive, opts))
334 }
335
336 pub fn get_pinned_for_update_cf<K: AsRef<[u8]>>(
337 &'_ self,
338 cf: &impl AsColumnFamilyRef,
339 key: K,
340 exclusive: bool,
341 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
342 DEFAULT_READ_OPTS.with(|opts| self.get_pinned_for_update_cf_opt(cf, key, exclusive, opts))
343 }
344
345 pub fn get_opt<K: AsRef<[u8]>>(
351 &self,
352 key: K,
353 readopts: &ReadOptions,
354 ) -> Result<Option<Vec<u8>>, Error> {
355 self.get_pinned_opt(key, readopts)
356 .map(|x| x.map(|v| v.as_ref().to_vec()))
357 }
358
359 pub fn get_pinned_opt<K: AsRef<[u8]>>(
360 &'_ self,
361 key: K,
362 readopts: &ReadOptions,
363 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
364 let key = key.as_ref();
365 unsafe {
366 let val = ffi_try!(ffi::rocksdb_transaction_get_pinned(
367 self.inner,
368 readopts.inner,
369 key.as_ptr() as *const c_char,
370 key.len(),
371 ));
372 if val.is_null() {
373 Ok(None)
374 } else {
375 Ok(Some(DBPinnableSlice::from_c(val)))
376 }
377 }
378 }
379
380 pub fn get_cf_opt<K: AsRef<[u8]>>(
388 &self,
389 cf: &impl AsColumnFamilyRef,
390 key: K,
391 readopts: &ReadOptions,
392 ) -> Result<Option<Vec<u8>>, Error> {
393 self.get_pinned_cf_opt(cf, key, readopts)
394 .map(|x| x.map(|v| v.as_ref().to_vec()))
395 }
396
397 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
398 &'_ self,
399 cf: &impl AsColumnFamilyRef,
400 key: K,
401 readopts: &ReadOptions,
402 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
403 let key = key.as_ref();
404 unsafe {
405 let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_cf(
406 self.inner,
407 readopts.inner,
408 cf.inner(),
409 key.as_ptr() as *const c_char,
410 key.len(),
411 ));
412 if val.is_null() {
413 Ok(None)
414 } else {
415 Ok(Some(DBPinnableSlice::from_c(val)))
416 }
417 }
418 }
419
420 pub fn get_for_update_opt<K: AsRef<[u8]>>(
429 &self,
430 key: K,
431 exclusive: bool,
432 opts: &ReadOptions,
433 ) -> Result<Option<Vec<u8>>, Error> {
434 self.get_pinned_for_update_opt(key, exclusive, opts)
435 .map(|x| x.map(|v| v.as_ref().to_vec()))
436 }
437
438 pub fn get_pinned_for_update_opt<K: AsRef<[u8]>>(
439 &'_ self,
440 key: K,
441 exclusive: bool,
442 opts: &ReadOptions,
443 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
444 let key = key.as_ref();
445 unsafe {
446 let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_for_update(
447 self.inner,
448 opts.inner,
449 key.as_ptr() as *const c_char,
450 key.len() as size_t,
451 u8::from(exclusive),
452 ));
453 if val.is_null() {
454 Ok(None)
455 } else {
456 Ok(Some(DBPinnableSlice::from_c(val)))
457 }
458 }
459 }
460
461 pub fn get_for_update_cf_opt<K: AsRef<[u8]>>(
490 &self,
491 cf: &impl AsColumnFamilyRef,
492 key: K,
493 exclusive: bool,
494 opts: &ReadOptions,
495 ) -> Result<Option<Vec<u8>>, Error> {
496 self.get_pinned_for_update_cf_opt(cf, key, exclusive, opts)
497 .map(|x| x.map(|v| v.as_ref().to_vec()))
498 }
499
500 pub fn get_pinned_for_update_cf_opt<K: AsRef<[u8]>>(
501 &'_ self,
502 cf: &impl AsColumnFamilyRef,
503 key: K,
504 exclusive: bool,
505 opts: &ReadOptions,
506 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
507 let key = key.as_ref();
508 unsafe {
509 let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_for_update_cf(
510 self.inner,
511 opts.inner,
512 cf.inner(),
513 key.as_ptr() as *const c_char,
514 key.len() as size_t,
515 u8::from(exclusive),
516 ));
517 if val.is_null() {
518 Ok(None)
519 } else {
520 Ok(Some(DBPinnableSlice::from_c(val)))
521 }
522 }
523 }
524
525 pub fn multi_get<K, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
527 where
528 K: AsRef<[u8]>,
529 I: IntoIterator<Item = K>,
530 {
531 DEFAULT_READ_OPTS.with(|opts| self.multi_get_opt(keys, opts))
532 }
533
534 pub fn multi_get_opt<K, I>(
536 &self,
537 keys: I,
538 readopts: &ReadOptions,
539 ) -> Vec<Result<Option<Vec<u8>>, Error>>
540 where
541 K: AsRef<[u8]>,
542 I: IntoIterator<Item = K>,
543 {
544 let owned_keys: Vec<K> = keys.into_iter().collect();
545 let (ptr_keys, keys_sizes): (Vec<*const c_char>, Vec<usize>) = owned_keys
546 .iter()
547 .map(|k| {
548 let key = k.as_ref();
549 (key.as_ptr() as *const c_char, key.len())
550 })
551 .unzip();
552
553 let mut values: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
554 let mut values_sizes: Vec<usize> = Vec::with_capacity(ptr_keys.len());
555 let mut errors: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
556 unsafe {
557 ffi::rocksdb_transaction_multi_get(
558 self.inner,
559 readopts.inner,
560 ptr_keys.len(),
561 ptr_keys.as_ptr(),
562 keys_sizes.as_ptr(),
563 values.as_mut_ptr(),
564 values_sizes.as_mut_ptr(),
565 errors.as_mut_ptr(),
566 );
567 }
568
569 unsafe {
570 values.set_len(ptr_keys.len());
571 values_sizes.set_len(ptr_keys.len());
572 errors.set_len(ptr_keys.len());
573 }
574
575 convert_values(values, values_sizes, errors)
576 }
577
578 pub fn multi_get_cf<'a, 'b: 'a, K, I, W>(
580 &'a self,
581 keys: I,
582 ) -> Vec<Result<Option<Vec<u8>>, Error>>
583 where
584 K: AsRef<[u8]>,
585 I: IntoIterator<Item = (&'b W, K)>,
586 W: 'b + AsColumnFamilyRef,
587 {
588 DEFAULT_READ_OPTS.with(|opts| self.multi_get_cf_opt(keys, opts))
589 }
590
591 pub fn multi_get_cf_opt<'a, 'b: 'a, K, I, W>(
593 &'a self,
594 keys: I,
595 readopts: &ReadOptions,
596 ) -> Vec<Result<Option<Vec<u8>>, Error>>
597 where
598 K: AsRef<[u8]>,
599 I: IntoIterator<Item = (&'b W, K)>,
600 W: 'b + AsColumnFamilyRef,
601 {
602 let cfs_and_owned_keys: Vec<(&'b W, K)> = keys.into_iter().collect();
603 let (ptr_keys, keys_sizes): (Vec<*const c_char>, Vec<usize>) = cfs_and_owned_keys
604 .iter()
605 .map(|(_, k)| {
606 let key = k.as_ref();
607 (key.as_ptr() as *const c_char, key.len())
608 })
609 .unzip();
610 let ptr_cfs: Vec<*const ffi::rocksdb_column_family_handle_t> = cfs_and_owned_keys
611 .iter()
612 .map(|(c, _)| c.inner().cast_const())
613 .collect();
614 let mut values: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
615 let mut values_sizes: Vec<usize> = Vec::with_capacity(ptr_keys.len());
616 let mut errors: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
617 unsafe {
618 ffi::rocksdb_transaction_multi_get_cf(
619 self.inner,
620 readopts.inner,
621 ptr_cfs.as_ptr(),
622 ptr_keys.len(),
623 ptr_keys.as_ptr(),
624 keys_sizes.as_ptr(),
625 values.as_mut_ptr(),
626 values_sizes.as_mut_ptr(),
627 errors.as_mut_ptr(),
628 );
629 }
630
631 unsafe {
632 values.set_len(ptr_keys.len());
633 values_sizes.set_len(ptr_keys.len());
634 errors.set_len(ptr_keys.len());
635 }
636
637 convert_values(values, values_sizes, errors)
638 }
639
640 pub fn multi_get_for_update<K, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
646 where
647 K: AsRef<[u8]>,
648 I: IntoIterator<Item = K>,
649 {
650 DEFAULT_READ_OPTS.with(|opts| self.multi_get_for_update_opt(keys, opts))
651 }
652
653 pub fn multi_get_for_update_opt<K, I>(
660 &self,
661 keys: I,
662 readopts: &ReadOptions,
663 ) -> Vec<Result<Option<Vec<u8>>, Error>>
664 where
665 K: AsRef<[u8]>,
666 I: IntoIterator<Item = K>,
667 {
668 let owned_keys: Vec<K> = keys.into_iter().collect();
669 let (ptr_keys, keys_sizes): (Vec<*const c_char>, Vec<usize>) = owned_keys
670 .iter()
671 .map(|k| {
672 let key = k.as_ref();
673 (key.as_ptr() as *const c_char, key.len())
674 })
675 .unzip();
676
677 let mut values: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
678 let mut values_sizes: Vec<usize> = Vec::with_capacity(ptr_keys.len());
679 let mut errors: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
680 unsafe {
681 ffi::rocksdb_transaction_multi_get_for_update(
682 self.inner,
683 readopts.inner,
684 ptr_keys.len(),
685 ptr_keys.as_ptr(),
686 keys_sizes.as_ptr(),
687 values.as_mut_ptr(),
688 values_sizes.as_mut_ptr(),
689 errors.as_mut_ptr(),
690 );
691 }
692
693 unsafe {
694 values.set_len(ptr_keys.len());
695 values_sizes.set_len(ptr_keys.len());
696 errors.set_len(ptr_keys.len());
697 }
698
699 convert_values(values, values_sizes, errors)
700 }
701
702 pub fn multi_get_for_update_cf<'a, 'b: 'a, K, I, W>(
709 &'a self,
710 keys: I,
711 ) -> Vec<Result<Option<Vec<u8>>, Error>>
712 where
713 K: AsRef<[u8]>,
714 I: IntoIterator<Item = (&'b W, K)>,
715 W: 'b + AsColumnFamilyRef,
716 {
717 DEFAULT_READ_OPTS.with(|opts| self.multi_get_for_update_cf_opt(keys, opts))
718 }
719
720 pub fn multi_get_for_update_cf_opt<'a, 'b: 'a, K, I, W>(
735 &'a self,
736 keys: I,
737 readopts: &ReadOptions,
738 ) -> Vec<Result<Option<Vec<u8>>, Error>>
739 where
740 K: AsRef<[u8]>,
741 I: IntoIterator<Item = (&'b W, K)>,
742 W: 'b + AsColumnFamilyRef,
743 {
744 let cfs_and_owned_keys: Vec<(&'b W, K)> = keys.into_iter().collect();
745 let (ptr_keys, keys_sizes): (Vec<*const c_char>, Vec<usize>) = cfs_and_owned_keys
746 .iter()
747 .map(|(_, k)| {
748 let key = k.as_ref();
749 (key.as_ptr() as *const c_char, key.len())
750 })
751 .unzip();
752 let ptr_cfs: Vec<*const ffi::rocksdb_column_family_handle_t> = cfs_and_owned_keys
753 .iter()
754 .map(|(c, _)| c.inner().cast_const())
755 .collect();
756 let mut values: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
757 let mut values_sizes: Vec<usize> = Vec::with_capacity(ptr_keys.len());
758 let mut errors: Vec<*mut c_char> = Vec::with_capacity(ptr_keys.len());
759 unsafe {
760 ffi::rocksdb_transaction_multi_get_for_update_cf(
761 self.inner,
762 readopts.inner,
763 ptr_cfs.as_ptr(),
764 ptr_keys.len(),
765 ptr_keys.as_ptr(),
766 keys_sizes.as_ptr(),
767 values.as_mut_ptr(),
768 values_sizes.as_mut_ptr(),
769 errors.as_mut_ptr(),
770 );
771 }
772
773 unsafe {
774 values.set_len(ptr_keys.len());
775 values_sizes.set_len(ptr_keys.len());
776 errors.set_len(ptr_keys.len());
777 }
778
779 convert_values(values, values_sizes, errors)
780 }
781
782 pub fn put<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) -> Result<(), Error> {
788 let key = key.as_ref();
789 let value = value.as_ref();
790 unsafe {
791 ffi_try!(ffi::rocksdb_transaction_put(
792 self.inner,
793 key.as_ptr() as *const c_char,
794 key.len() as size_t,
795 value.as_ptr() as *const c_char,
796 value.len() as size_t,
797 ));
798 Ok(())
799 }
800 }
801
802 pub fn put_cf<K: AsRef<[u8]>, V: AsRef<[u8]>>(
818 &self,
819 cf: &impl AsColumnFamilyRef,
820 key: K,
821 value: V,
822 ) -> Result<(), Error> {
823 let key = key.as_ref();
824 let value = value.as_ref();
825 unsafe {
826 ffi_try!(ffi::rocksdb_transaction_put_cf(
827 self.inner,
828 cf.inner(),
829 key.as_ptr() as *const c_char,
830 key.len() as size_t,
831 value.as_ptr() as *const c_char,
832 value.len() as size_t,
833 ));
834 Ok(())
835 }
836 }
837
838 pub fn merge<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) -> Result<(), Error> {
844 let key = key.as_ref();
845 let value = value.as_ref();
846 unsafe {
847 ffi_try!(ffi::rocksdb_transaction_merge(
848 self.inner,
849 key.as_ptr() as *const c_char,
850 key.len() as size_t,
851 value.as_ptr() as *const c_char,
852 value.len() as size_t
853 ));
854 Ok(())
855 }
856 }
857
858 pub fn merge_cf<K: AsRef<[u8]>, V: AsRef<[u8]>>(
874 &self,
875 cf: &impl AsColumnFamilyRef,
876 key: K,
877 value: V,
878 ) -> Result<(), Error> {
879 let key = key.as_ref();
880 let value = value.as_ref();
881 unsafe {
882 ffi_try!(ffi::rocksdb_transaction_merge_cf(
883 self.inner,
884 cf.inner(),
885 key.as_ptr() as *const c_char,
886 key.len() as size_t,
887 value.as_ptr() as *const c_char,
888 value.len() as size_t
889 ));
890 Ok(())
891 }
892 }
893
894 pub fn delete<K: AsRef<[u8]>>(&self, key: K) -> Result<(), Error> {
900 let key = key.as_ref();
901 unsafe {
902 ffi_try!(ffi::rocksdb_transaction_delete(
903 self.inner,
904 key.as_ptr() as *const c_char,
905 key.len() as size_t
906 ));
907 }
908 Ok(())
909 }
910
911 pub fn delete_cf<K: AsRef<[u8]>>(
926 &self,
927 cf: &impl AsColumnFamilyRef,
928 key: K,
929 ) -> Result<(), Error> {
930 let key = key.as_ref();
931 unsafe {
932 ffi_try!(ffi::rocksdb_transaction_delete_cf(
933 self.inner,
934 cf.inner(),
935 key.as_ptr() as *const c_char,
936 key.len() as size_t
937 ));
938 }
939 Ok(())
940 }
941
942 pub fn iterator<'a: 'b, 'b>(
943 &'a self,
944 mode: IteratorMode,
945 ) -> DBIteratorWithThreadMode<'b, Self> {
946 let readopts = ReadOptions::default();
947 self.iterator_opt(mode, readopts)
948 }
949
950 pub fn iterator_opt<'a: 'b, 'b>(
951 &'a self,
952 mode: IteratorMode,
953 readopts: ReadOptions,
954 ) -> DBIteratorWithThreadMode<'b, Self> {
955 DBIteratorWithThreadMode::new(self, readopts, mode)
956 }
957
958 pub fn iterator_cf_opt<'a: 'b, 'b>(
961 &'a self,
962 cf_handle: &impl AsColumnFamilyRef,
963 readopts: ReadOptions,
964 mode: IteratorMode,
965 ) -> DBIteratorWithThreadMode<'b, Self> {
966 DBIteratorWithThreadMode::new_cf(self, cf_handle.inner(), readopts, mode)
967 }
968
969 pub fn full_iterator<'a: 'b, 'b>(
973 &'a self,
974 mode: IteratorMode,
975 ) -> DBIteratorWithThreadMode<'b, Self> {
976 let mut opts = ReadOptions::default();
977 opts.set_total_order_seek(true);
978 DBIteratorWithThreadMode::new(self, opts, mode)
979 }
980
981 pub fn prefix_iterator<'a: 'b, 'b, P: AsRef<[u8]>>(
982 &'a self,
983 prefix: P,
984 ) -> DBIteratorWithThreadMode<'b, Self> {
985 let mut opts = ReadOptions::default();
986 opts.set_prefix_same_as_start(true);
987 DBIteratorWithThreadMode::new(
988 self,
989 opts,
990 IteratorMode::From(prefix.as_ref(), Direction::Forward),
991 )
992 }
993
994 pub fn iterator_cf<'a: 'b, 'b>(
995 &'a self,
996 cf_handle: &impl AsColumnFamilyRef,
997 mode: IteratorMode,
998 ) -> DBIteratorWithThreadMode<'b, Self> {
999 let opts = ReadOptions::default();
1000 DBIteratorWithThreadMode::new_cf(self, cf_handle.inner(), opts, mode)
1001 }
1002
1003 pub fn full_iterator_cf<'a: 'b, 'b>(
1004 &'a self,
1005 cf_handle: &impl AsColumnFamilyRef,
1006 mode: IteratorMode,
1007 ) -> DBIteratorWithThreadMode<'b, Self> {
1008 let mut opts = ReadOptions::default();
1009 opts.set_total_order_seek(true);
1010 DBIteratorWithThreadMode::new_cf(self, cf_handle.inner(), opts, mode)
1011 }
1012
1013 pub fn prefix_iterator_cf<'a, P: AsRef<[u8]>>(
1014 &'a self,
1015 cf_handle: &impl AsColumnFamilyRef,
1016 prefix: P,
1017 ) -> DBIteratorWithThreadMode<'a, Self> {
1018 let mut opts = ReadOptions::default();
1019 opts.set_prefix_same_as_start(true);
1020 DBIteratorWithThreadMode::<'a, Self>::new_cf(
1021 self,
1022 cf_handle.inner(),
1023 opts,
1024 IteratorMode::From(prefix.as_ref(), Direction::Forward),
1025 )
1026 }
1027
1028 pub fn raw_iterator<'a: 'b, 'b>(&'a self) -> DBRawIteratorWithThreadMode<'b, Self> {
1030 let opts = ReadOptions::default();
1031 DBRawIteratorWithThreadMode::new(self, opts)
1032 }
1033
1034 pub fn raw_iterator_cf<'a: 'b, 'b>(
1036 &'a self,
1037 cf_handle: &impl AsColumnFamilyRef,
1038 ) -> DBRawIteratorWithThreadMode<'b, Self> {
1039 let opts = ReadOptions::default();
1040 DBRawIteratorWithThreadMode::new_cf(self, cf_handle.inner(), opts)
1041 }
1042
1043 pub fn raw_iterator_opt<'a: 'b, 'b>(
1045 &'a self,
1046 readopts: ReadOptions,
1047 ) -> DBRawIteratorWithThreadMode<'b, Self> {
1048 DBRawIteratorWithThreadMode::new(self, readopts)
1049 }
1050
1051 pub fn raw_iterator_cf_opt<'a: 'b, 'b>(
1053 &'a self,
1054 cf_handle: &impl AsColumnFamilyRef,
1055 readopts: ReadOptions,
1056 ) -> DBRawIteratorWithThreadMode<'b, Self> {
1057 DBRawIteratorWithThreadMode::new_cf(self, cf_handle.inner(), readopts)
1058 }
1059
1060 pub fn get_writebatch(&self) -> WriteBatchWithTransaction<true> {
1061 unsafe {
1062 let wi = ffi::rocksdb_transaction_get_writebatch_wi(self.inner);
1063 let mut len: usize = 0;
1064 let ptr = ffi::rocksdb_writebatch_wi_data(wi, std::ptr::from_mut(&mut len));
1065 let writebatch = ffi::rocksdb_writebatch_create_from(ptr, len);
1066 ffi::rocksdb_free(wi as *mut c_void);
1067 WriteBatchWithTransaction { inner: writebatch }
1068 }
1069 }
1070
1071 pub fn rebuild_from_writebatch(
1072 &self,
1073 writebatch: &WriteBatchWithTransaction<true>,
1074 ) -> Result<(), Error> {
1075 unsafe {
1076 ffi_try!(ffi::rocksdb_transaction_rebuild_from_writebatch(
1077 self.inner,
1078 writebatch.inner
1079 ));
1080 }
1081 Ok(())
1082 }
1083
1084 pub fn rebuild_from_writebatch_wi(
1103 &self,
1104 writebatch: &WriteBatchWithIndex,
1105 ) -> Result<(), Error> {
1106 unsafe {
1107 ffi_try!(ffi::rocksdb_transaction_rebuild_from_writebatch_wi(
1108 self.inner,
1109 writebatch.inner
1110 ));
1111 }
1112 Ok(())
1113 }
1114
1115 pub fn put_log_data<V: AsRef<[u8]>>(&self, log_data: V) {
1128 let log_data = log_data.as_ref();
1129 unsafe {
1130 ffi::rocksdb_transaction_put_log_data(
1131 self.inner,
1132 log_data.as_ptr() as *const c_char,
1133 log_data.len() as size_t,
1134 );
1135 }
1136 }
1137
1138 pub fn set_commit_timestamp(&self, val: u64) {
1144 unsafe {
1145 ffi::rocksdb_transaction_set_commit_timestamp(self.inner, val);
1146 }
1147 }
1148
1149 pub fn set_read_timestamp_for_validation(&self, val: u64) {
1155 unsafe {
1156 ffi::rocksdb_transaction_set_read_timestamp_for_validation(self.inner, val);
1157 }
1158 }
1159}
1160
1161impl<DB> Drop for Transaction<'_, DB> {
1162 fn drop(&mut self) {
1163 unsafe {
1164 ffi::rocksdb_transaction_destroy(self.inner);
1165 }
1166 }
1167}