@@ -15,9 +15,9 @@ use utils::environment::EnvironmentUtils;
1515use errors:: wallet:: WalletStorageError ;
1616use errors:: common:: CommonError ;
1717use services:: wallet:: language;
18- use super :: super :: indy_crypto:: utils:: json:: { JsonDecodable , JsonEncodable } ;
1918
20- use super :: { StorageIterator , WalletStorageType , WalletStorage , StorageEntity , EncryptedValue , Tag , TagName } ;
19+ use super :: { StorageIterator , WalletStorageType , WalletStorage , StorageEntity , EncryptedValue , Tag , TagName , FetchOptions } ;
20+ use super :: super :: SearchOptions ;
2121
2222const _SQLITE_DB: & str = "sqlite.db" ;
2323const _PLAIN_TAGS_QUERY: & str = "SELECT name, value from tags_plaintext where item_id = ?" ;
@@ -93,7 +93,8 @@ struct TagRetriever<'a> {
9393 encrypted_tags_stmt : rusqlite:: Statement < ' a > ,
9494}
9595
96- type TagRetrieverOwned = OwningHandle < Rc < rusqlite:: Connection > , Box < TagRetriever < ' static > > > ;
96+ type TagRetrieverOwned = OwningHandle < Rc < rusqlite:: Connection > , Box < TagRetriever < ' static > > >
97+ ;
9798
9899impl < ' a > TagRetriever < ' a > {
99100 fn new_owned ( conn : Rc < rusqlite:: Connection > ) -> Result < TagRetrieverOwned , WalletStorageError > {
@@ -139,44 +140,52 @@ struct SQLiteStorageIterator {
139140 Box < rusqlite:: Rows < ' static > > > > ,
140141 tag_retriever : Option < TagRetrieverOwned > ,
141142 options : FetchOptions ,
142- fetch_type_ : bool ,
143+ total_count : Option < usize > ,
143144}
144145
145146
146147impl SQLiteStorageIterator {
147- fn new ( stmt : OwningHandle < Rc < rusqlite:: Connection > , Box < rusqlite:: Statement < ' static > > > ,
148+ fn new ( stmt : Option < OwningHandle < Rc < rusqlite:: Connection > , Box < rusqlite:: Statement < ' static > > > > ,
148149 args : & [ & rusqlite:: types:: ToSql ] ,
149150 options : FetchOptions ,
150151 tag_retriever : Option < TagRetrieverOwned > ,
151- fetch_type_ : bool ) -> Result < SQLiteStorageIterator , WalletStorageError > {
152+ total_count : Option < usize > ) -> Result < SQLiteStorageIterator , WalletStorageError > {
152153 let mut iter = SQLiteStorageIterator {
153154 rows : None ,
154155 tag_retriever,
155156 options,
156- fetch_type_ ,
157+ total_count
157158 } ;
158- iter. rows = Some ( OwningHandle :: try_new (
159- stmt, |stmt|
160- unsafe {
161- ( * ( stmt as * mut rusqlite:: Statement ) ) . query ( args) . map ( Box :: new)
162- } ,
163- ) ?) ;
159+
160+ if let Some ( stmt) = stmt {
161+ iter. rows = Some ( OwningHandle :: try_new (
162+ stmt, |stmt|
163+ unsafe {
164+ ( * ( stmt as * mut rusqlite:: Statement ) ) . query ( args) . map ( Box :: new)
165+ } ,
166+ ) ?) ;
167+ }
164168 Ok ( iter)
165169 }
166170}
167171
168172
169173impl StorageIterator for SQLiteStorageIterator {
170174 fn next ( & mut self ) -> Result < Option < StorageEntity > , WalletStorageError > {
175+ // if records are not requested.
176+ if self . rows . is_none ( ) {
177+ return Ok ( None ) ;
178+ }
179+
171180 match self . rows . as_mut ( ) . unwrap ( ) . next ( ) {
172181 Some ( Ok ( row) ) => {
173182 let name = row. get ( 1 ) ;
174- let value = if self . options . fetch_value {
183+ let value = if self . options . retrieve_value {
175184 Some ( EncryptedValue :: new ( row. get ( 2 ) , row. get ( 3 ) ) )
176185 } else {
177186 None
178187 } ;
179- let tags = if self . options . fetch_tags {
188+ let tags = if self . options . retrieve_tags {
180189 match self . tag_retriever {
181190 Some ( ref mut tag_retriever) => Some ( tag_retriever. retrieve ( row. get ( 0 ) ) ?) ,
182191 None => return Err ( WalletStorageError :: CommonError (
@@ -186,7 +195,7 @@ impl StorageIterator for SQLiteStorageIterator {
186195 } else {
187196 None
188197 } ;
189- let type_ = if self . fetch_type_ {
198+ let type_ = if self . options . retrieve_type {
190199 Some ( row. get ( 4 ) )
191200 } else {
192201 None
@@ -197,45 +206,12 @@ impl StorageIterator for SQLiteStorageIterator {
197206 None => Ok ( None )
198207 }
199208 }
200- }
201-
202-
203- #[ derive( Debug , Deserialize , Serialize ) ]
204- struct FetchOptions {
205- #[ serde( rename="retrieveType" ) ]
206- fetch_type : bool ,
207- #[ serde( rename="retrieveValue" ) ]
208- fetch_value : bool ,
209- #[ serde( rename="retrieveTags" ) ]
210- fetch_tags : bool ,
211- }
212209
213- impl FetchOptions {
214- fn new ( fetch_type : bool , fetch_value : bool , fetch_tags : bool ) -> FetchOptions {
215- FetchOptions {
216- fetch_type : fetch_type,
217- fetch_value : fetch_value,
218- fetch_tags : fetch_tags,
219- }
210+ fn get_total_count ( & self ) -> Result < Option < usize > , WalletStorageError > {
211+ Ok ( self . total_count )
220212 }
221213}
222214
223- impl Default for FetchOptions {
224- fn default ( ) -> FetchOptions {
225- FetchOptions {
226- fetch_type : false ,
227- fetch_value : true ,
228- fetch_tags : false ,
229- }
230- }
231- }
232-
233- impl JsonEncodable for FetchOptions { }
234-
235- impl < ' a > JsonDecodable < ' a > for FetchOptions { }
236-
237-
238-
239215#[ derive( Debug ) ]
240216struct SQLiteStorage {
241217 conn : Rc < rusqlite:: Connection > ,
@@ -305,9 +281,10 @@ impl WalletStorage for SQLiteStorage {
305281 Err ( rusqlite:: Error :: QueryReturnedNoRows ) => return Err ( WalletStorageError :: ItemNotFound ) ,
306282 Err ( err) => return Err ( WalletStorageError :: from ( err) )
307283 } ;
308- let value = if options. fetch_value { Some ( EncryptedValue :: new ( item. 1 , item. 2 ) ) } else { None } ;
309- let type_ = if options. fetch_type { Some ( type_. clone ( ) ) } else { None } ;
310- let tags = if options. fetch_tags {
284+ let value = if options. retrieve_value
285+ { Some ( EncryptedValue :: new ( item. 1 , item. 2 ) ) } else { None } ;
286+ let type_ = if options. retrieve_type { Some ( type_. clone ( ) ) } else { None } ;
287+ let tags = if options. retrieve_tags {
311288 let mut tags = Vec :: new ( ) ;
312289
313290 // get all encrypted.
@@ -552,31 +529,55 @@ impl WalletStorage for SQLiteStorage {
552529 fn get_all ( & self ) -> Result < Box < StorageIterator > , WalletStorageError > {
553530 let statement = self . _prepare_statement ( "SELECT id, name, value, key, type FROM items;" ) ?;
554531 let fetch_options = FetchOptions {
555- fetch_type : true ,
556- fetch_value : true ,
557- fetch_tags : true ,
532+ retrieve_type : true ,
533+ retrieve_value : true ,
534+ retrieve_tags : true ,
558535 } ;
559536 let tag_retriever = Some ( TagRetriever :: new_owned ( self . conn . clone ( ) ) ?) ;
560537
561- let storage_iterator = SQLiteStorageIterator :: new ( statement, & [ ] , fetch_options, tag_retriever, true ) ?;
538+ let storage_iterator = SQLiteStorageIterator :: new ( Some ( statement) , & [ ] , fetch_options, tag_retriever, None ) ?;
562539 Ok ( Box :: new ( storage_iterator) )
563540 }
564541
565542 fn search ( & self , type_ : & Vec < u8 > , query : & language:: Operator , options : Option < & str > ) -> Result < Box < StorageIterator > , WalletStorageError > {
566- let fetch_options = match options {
567- None => FetchOptions :: default ( ) ,
543+ let search_options = match options {
544+ None => SearchOptions :: default ( ) ,
568545 Some ( option_str) => serde_json:: from_str ( option_str) ?
569546 } ;
570- let ( query_string, query_arguments) = query:: wql_to_sql ( type_, query, options) ?;
571547
572- let statement = self . _prepare_statement ( & query_string) ?;
573- let tag_retriever = if fetch_options. fetch_tags {
574- Some ( TagRetriever :: new_owned ( self . conn . clone ( ) ) ?)
575- } else {
576- None
577- } ;
578- let storage_iterator = SQLiteStorageIterator :: new ( statement, & query_arguments, fetch_options, tag_retriever, false ) ?;
579- Ok ( Box :: new ( storage_iterator) )
548+ let total_count: Option < usize > = if search_options. retrieve_total_count . unwrap_or ( false ) {
549+ let ( query_string, query_arguments) = query:: wql_to_sql_count ( type_, query) ?;
550+
551+ self . conn . query_row (
552+ & query_string,
553+ & query_arguments,
554+ |row| { let x: i64 = row. get ( 0 ) ; Some ( x as usize ) }
555+ ) ?
556+ } else { None } ;
557+
558+
559+ if search_options. retrieve_records . unwrap_or ( true ) {
560+ let fetch_options = FetchOptions {
561+ retrieve_value : search_options. retrieve_value . unwrap_or ( true ) ,
562+ retrieve_tags : search_options. retrieve_tags . unwrap_or ( false ) ,
563+ retrieve_type : search_options. retrieve_type . unwrap_or ( false ) ,
564+ } ;
565+
566+ let ( query_string, query_arguments) = query:: wql_to_sql ( type_, query, options) ?;
567+
568+ let statement = self . _prepare_statement ( & query_string) ?;
569+ let tag_retriever = if fetch_options. retrieve_tags {
570+ Some ( TagRetriever :: new_owned ( self . conn . clone ( ) ) ?)
571+ } else {
572+ None
573+ } ;
574+ let storage_iterator = SQLiteStorageIterator :: new ( Some ( statement) , & query_arguments, fetch_options, tag_retriever, total_count) ?;
575+ Ok ( Box :: new ( storage_iterator) )
576+ }
577+ else {
578+ let storage_iterator = SQLiteStorageIterator :: new ( None , & [ ] , FetchOptions :: default ( ) , None , total_count) ?;
579+ Ok ( Box :: new ( storage_iterator) )
580+ }
580581 }
581582
582583 fn close ( & mut self ) -> Result < ( ) , WalletStorageError > {
0 commit comments