11// use ic_cdk::api::stable;
2- // use icfs::StableMemory;
2+ use icfs:: StableMemory ;
33use std:: convert:: TryInto ;
4- use std:: io:: { self , ErrorKind } ;
4+ use std:: io:: { self , ErrorKind , Read , Seek , SeekFrom , Write } ;
55use std:: sync:: { Arc , Mutex } ;
66use std:: time:: Duration ;
77
@@ -10,6 +10,11 @@ use sqlite_vfs::{LockKind, OpenKind, OpenOptions, Vfs};
1010pub const DB_NAME : & str = "main.db" ;
1111pub const VFS_NAME : & str = "ic-sqlite" ;
1212
13+ thread_local ! {
14+ static STABLE_MEMORY : std:: cell:: RefCell <StableMemory >
15+ = std:: cell:: RefCell :: new( StableMemory :: default ( ) ) ;
16+ }
17+
1318#[ derive( Default ) ]
1419pub struct PagesVfs < const PAGE_SIZE : usize > {
1520 lock_state : Arc < Mutex < LockState > > ,
@@ -69,6 +74,10 @@ impl<const PAGE_SIZE: usize> Vfs for PagesVfs<PAGE_SIZE> {
6974 fn random ( & self , buffer : & mut [ i8 ] ) {
7075 // Calling `raw_rand` would be preferable, but this method can't be async.
7176 // let raw_rand: Vec<u8> = call(Principal::management_canister(), "raw_rand", ()).await;
77+ //
78+ // We can't write and register a custom getrandom function either because that can't be async:
79+ // * https://github.com/rust-random/rand/blob/b73640705d6714509f8ceccc49e8df996fa19f51/README.md#wasm-support
80+ // * https://docs.rs/getrandom/0.2.7/getrandom/macro.register_custom_getrandom.html
7281 todo ! ( ) ;
7382 // rand::Rng::fill(&mut rand::thread_rng(), buffer);
7483 }
@@ -187,27 +196,39 @@ impl<const PAGE_SIZE: usize> sqlite_vfs::DatabaseHandle for Connection<PAGE_SIZE
187196 }
188197}
189198
199+ fn put_page < const PAGE_SIZE : usize > ( ix : u32 , data : & [ u8 ; PAGE_SIZE ] ) {
200+ STABLE_MEMORY . with ( |stable_memory| {
201+ let mut stable_memory = * stable_memory. borrow ( ) ;
202+ let page_size: u64 = PAGE_SIZE . try_into ( ) . unwrap ( ) ;
203+ let offset: u64 = ix as u64 * page_size;
204+ stable_memory. seek ( SeekFrom :: Start ( offset) ) . unwrap ( ) ;
205+ stable_memory. write ( data) . unwrap ( ) ;
206+ } )
207+ }
208+
190209impl < const PAGE_SIZE : usize > Connection < PAGE_SIZE > {
191210 fn get_page ( ix : u32 ) -> [ u8 ; PAGE_SIZE ] {
192- let mut data = [ 0u8 ; PAGE_SIZE ] ;
193- unsafe { crate :: get_page ( ix, data. as_mut_ptr ( ) ) } ;
194- data
211+ STABLE_MEMORY . with ( |stable_memory| {
212+ let mut stable_memory = * stable_memory. borrow ( ) ;
213+ let mut data = [ 0u8 ; PAGE_SIZE ] ;
214+ let page_size: u64 = PAGE_SIZE . try_into ( ) . unwrap ( ) ;
215+ let offset: u64 = ix as u64 * page_size;
216+ stable_memory. seek ( SeekFrom :: Start ( offset) ) . unwrap ( ) ;
217+ stable_memory. read ( & mut data) . unwrap ( ) ;
218+ data
219+ } )
195220 }
196221
197222 fn put_page ( ix : u32 , data : & [ u8 ; PAGE_SIZE ] ) {
198- unsafe {
199- crate :: put_page ( ix, data. as_ptr ( ) ) ;
200- }
223+ put_page ( ix, data)
201224 }
202225
203226 fn del_page ( ix : u32 ) {
204- unsafe {
205- crate :: del_page ( ix) ;
206- }
227+ put_page ( ix, & [ 0 ; PAGE_SIZE ] )
207228 }
208229
209230 fn page_count ( ) -> usize {
210- unsafe { crate :: page_count ( ) as usize }
231+ StableMemory :: size ( ) . try_into ( ) . unwrap ( )
211232 }
212233
213234 fn lock ( & mut self , to : LockKind ) -> bool {
0 commit comments