@@ -139,56 +139,56 @@ pub struct SQLiteWriter {
139139impl SQLiteWriter {
140140 /// Open an in-memory database.
141141 pub fn open_in_memory ( ) -> Result < Self > {
142- let conn = Connection :: open_in_memory ( ) ?;
143- Self :: init ( & conn) ?;
142+ let mut conn = Connection :: open_in_memory ( ) ?;
143+ Self :: init ( & mut conn) ?;
144144 Ok ( Self { conn } )
145145 }
146146
147147 /// Open a file database. If the file does not exist, it is automatically created.
148148 /// An error is returned if the database version is not supported.
149149 pub fn open < P : AsRef < Path > > ( path : P ) -> Result < Self > {
150150 let is_new = !path. as_ref ( ) . exists ( ) ;
151- let conn = Connection :: open ( path) ?;
151+ let mut conn = Connection :: open ( path) ?;
152152 set_pragmas_and_functions ( & conn) ?;
153153 if is_new {
154- Self :: init ( & conn) ?;
154+ Self :: init ( & mut conn) ?;
155155 } else {
156156 check_version ( & conn) ?;
157157 }
158158 Ok ( Self { conn } )
159159 }
160160
161161 /// Create database tables and write metadata.
162- fn init ( conn : & Connection ) -> Result < ( ) > {
163- conn. execute ( "BEGIN" , [ ] ) ?;
164- conn . execute_batch ( SCHEMA ) ?;
165- conn . execute ( "INSERT INTO metadata (version) VALUES (?)" , [ VERSION ] ) ?;
166- conn . execute ( "COMMIT" , [ ] ) ?;
162+ fn init ( conn : & mut Connection ) -> Result < ( ) > {
163+ let tx = conn. transaction ( ) ?;
164+ tx . execute_batch ( SCHEMA ) ?;
165+ tx . execute ( "INSERT INTO metadata (version) VALUES (?)" , [ VERSION ] ) ?;
166+ tx . commit ( ) ?;
167167 Ok ( ( ) )
168168 }
169169
170170 /// Clean all data from the database.
171171 pub fn clean_all ( & mut self ) -> Result < usize > {
172- self . conn . execute ( "BEGIN" , [ ] ) ?;
173- let count = self . clean_all_inner ( ) ?;
174- self . conn . execute ( "COMMIT" , [ ] ) ?;
172+ let tx = self . conn . transaction ( ) ?;
173+ let count = Self :: clean_all_inner ( & tx ) ?;
174+ tx . commit ( ) ?;
175175 Ok ( count)
176176 }
177177
178178 /// Clean all data from the database.
179179 ///
180180 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
181- fn clean_all_inner ( & mut self ) -> Result < usize > {
181+ fn clean_all_inner ( conn : & Connection ) -> Result < usize > {
182182 {
183- let mut stmt = self . conn . prepare_cached ( "DELETE FROM file_paths" ) ?;
183+ let mut stmt = conn. prepare_cached ( "DELETE FROM file_paths" ) ?;
184184 stmt. execute ( [ ] ) ?;
185185 }
186186 {
187- let mut stmt = self . conn . prepare_cached ( "DELETE FROM root_paths" ) ?;
187+ let mut stmt = conn. prepare_cached ( "DELETE FROM root_paths" ) ?;
188188 stmt. execute ( [ ] ) ?;
189189 }
190190 let count = {
191- let mut stmt = self . conn . prepare_cached ( "DELETE FROM graphs" ) ?;
191+ let mut stmt = conn. prepare_cached ( "DELETE FROM graphs" ) ?;
192192 stmt. execute ( [ ] ) ?
193193 } ;
194194 Ok ( count)
@@ -197,33 +197,27 @@ impl SQLiteWriter {
197197 /// Clean file data from the database. If recursive is true, data for all descendants of
198198 /// that file is cleaned.
199199 pub fn clean_file ( & mut self , file : & Path ) -> Result < usize > {
200- self . conn . execute ( "BEGIN" , [ ] ) ?;
201- let count = self . clean_file_inner ( file) ?;
202- self . conn . execute ( "COMMIT" , [ ] ) ?;
200+ let tx = self . conn . transaction ( ) ?;
201+ let count = Self :: clean_file_inner ( & tx , file) ?;
202+ tx . commit ( ) ?;
203203 Ok ( count)
204204 }
205205
206206 /// Clean file data from the database.
207207 ///
208208 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
209- fn clean_file_inner ( & mut self , file : & Path ) -> Result < usize > {
209+ fn clean_file_inner ( conn : & Connection , file : & Path ) -> Result < usize > {
210210 let file = file. to_string_lossy ( ) ;
211211 {
212- let mut stmt = self
213- . conn
214- . prepare_cached ( "DELETE FROM file_paths WHERE file=?" ) ?;
212+ let mut stmt = conn. prepare_cached ( "DELETE FROM file_paths WHERE file=?" ) ?;
215213 stmt. execute ( [ & file] ) ?;
216214 }
217215 {
218- let mut stmt = self
219- . conn
220- . prepare_cached ( "DELETE FROM root_paths WHERE file=?" ) ?;
216+ let mut stmt = conn. prepare_cached ( "DELETE FROM root_paths WHERE file=?" ) ?;
221217 stmt. execute ( [ & file] ) ?;
222218 }
223219 let count = {
224- let mut stmt = self
225- . conn
226- . prepare_cached ( "DELETE FROM graphs WHERE file=?" ) ?;
220+ let mut stmt = conn. prepare_cached ( "DELETE FROM graphs WHERE file=?" ) ?;
227221 stmt. execute ( [ & file] ) ?
228222 } ;
229223 Ok ( count)
@@ -232,55 +226,56 @@ impl SQLiteWriter {
232226 /// Clean file or directory data from the database. Data for all decendants of the given path
233227 /// is cleaned.
234228 pub fn clean_file_or_directory ( & mut self , file_or_directory : & Path ) -> Result < usize > {
235- self . conn . execute ( "BEGIN" , [ ] ) ?;
236- let count = self . clean_file_or_directory_inner ( file_or_directory) ?;
237- self . conn . execute ( "COMMIT" , [ ] ) ?;
229+ let tx = self . conn . transaction ( ) ?;
230+ let count = Self :: clean_file_or_directory_inner ( & tx , file_or_directory) ?;
231+ tx . commit ( ) ?;
238232 Ok ( count)
239233 }
240234
241235 /// Clean file or directory data from the database. Data for all decendants of the given path
242236 /// is cleaned.
243237 ///
244238 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
245- fn clean_file_or_directory_inner ( & mut self , file_or_directory : & Path ) -> Result < usize > {
239+ fn clean_file_or_directory_inner ( conn : & Connection , file_or_directory : & Path ) -> Result < usize > {
246240 let file_or_directory = file_or_directory. to_string_lossy ( ) ;
247241 {
248- let mut stmt = self
249- . conn
250- . prepare_cached ( "DELETE FROM file_paths WHERE path_descendant_of(file, ?)" ) ?;
242+ let mut stmt =
243+ conn. prepare_cached ( "DELETE FROM file_paths WHERE path_descendant_of(file, ?)" ) ?;
251244 stmt. execute ( [ & file_or_directory] ) ?;
252245 }
253246 {
254- let mut stmt = self
255- . conn
256- . prepare_cached ( "DELETE FROM root_paths WHERE path_descendant_of(file, ?)" ) ?;
247+ let mut stmt =
248+ conn. prepare_cached ( "DELETE FROM root_paths WHERE path_descendant_of(file, ?)" ) ?;
257249 stmt. execute ( [ & file_or_directory] ) ?;
258250 }
259251 let count = {
260- let mut stmt = self
261- . conn
262- . prepare_cached ( "DELETE FROM graphs WHERE path_descendant_of(file, ?)" ) ?;
252+ let mut stmt =
253+ conn. prepare_cached ( "DELETE FROM graphs WHERE path_descendant_of(file, ?)" ) ?;
263254 stmt. execute ( [ & file_or_directory] ) ?
264255 } ;
265256 Ok ( count)
266257 }
267258
268259 /// Store an error, indicating that indexing this file failed.
269260 pub fn store_error_for_file ( & mut self , file : & Path , tag : & str , error : & str ) -> Result < ( ) > {
270- self . conn . execute ( "BEGIN" , [ ] ) ?;
271- self . store_error_for_file_inner ( file, tag, error) ?;
272- self . conn . execute ( "COMMIT" , [ ] ) ?;
261+ let tx = self . conn . transaction ( ) ?;
262+ Self :: store_error_for_file_inner ( & tx , file, tag, error) ?;
263+ tx . commit ( ) ?;
273264 Ok ( ( ) )
274265 }
275266
276267 /// Store an error, indicating that indexing this file failed.
277268 ///
278269 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
279- fn store_error_for_file_inner ( & mut self , file : & Path , tag : & str , error : & str ) -> Result < ( ) > {
270+ fn store_error_for_file_inner (
271+ conn : & Connection ,
272+ file : & Path ,
273+ tag : & str ,
274+ error : & str ,
275+ ) -> Result < ( ) > {
280276 copious_debugging ! ( "--> Store error for {}" , file. display( ) ) ;
281- let mut stmt = self
282- . conn
283- . prepare_cached ( "INSERT INTO graphs (file, tag, error, json) VALUES (?, ?, ?, ?)" ) ?;
277+ let mut stmt =
278+ conn. prepare_cached ( "INSERT INTO graphs (file, tag, error, json) VALUES (?, ?, ?, ?)" ) ?;
284279 let graph = crate :: serde:: StackGraph :: default ( ) ;
285280 stmt. execute ( (
286281 & file. to_string_lossy ( ) ,
@@ -304,28 +299,27 @@ impl SQLiteWriter {
304299 IP : IntoIterator < Item = & ' a PartialPath > ,
305300 {
306301 let path = Path :: new ( graph[ file] . name ( ) ) ;
307- self . conn . execute ( "BEGIN" , [ ] ) ?;
308- self . clean_file_inner ( path) ?;
309- self . store_graph_for_file_inner ( graph, file, tag) ?;
310- self . store_partial_paths_for_file_inner ( graph, file, partials, paths) ?;
311- self . conn . execute ( "COMMIT" , [ ] ) ?;
302+ let tx = self . conn . transaction ( ) ?;
303+ Self :: clean_file_inner ( & tx , path) ?;
304+ Self :: store_graph_for_file_inner ( & tx , graph, file, tag) ?;
305+ Self :: store_partial_paths_for_file_inner ( & tx , graph, file, partials, paths) ?;
306+ tx . commit ( ) ?;
312307 Ok ( ( ) )
313308 }
314309
315310 /// Store the file graph.
316311 ///
317312 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
318313 fn store_graph_for_file_inner (
319- & mut self ,
314+ conn : & Connection ,
320315 graph : & StackGraph ,
321316 file : Handle < File > ,
322317 tag : & str ,
323318 ) -> Result < ( ) > {
324319 let file_str = graph[ file] . name ( ) ;
325320 copious_debugging ! ( "--> Store graph for {}" , file_str) ;
326- let mut stmt = self
327- . conn
328- . prepare_cached ( "INSERT INTO graphs (file, tag, json) VALUES (?, ?, ?)" ) ?;
321+ let mut stmt =
322+ conn. prepare_cached ( "INSERT INTO graphs (file, tag, json) VALUES (?, ?, ?)" ) ?;
329323 let graph = serde:: StackGraph :: from_graph_filter ( graph, & FileFilter ( file) ) ;
330324 stmt. execute ( ( file_str, tag, & serde_json:: to_vec ( & graph) ?) ) ?;
331325 Ok ( ( ) )
@@ -335,7 +329,7 @@ impl SQLiteWriter {
335329 ///
336330 /// This is an inner method, which does not wrap individual SQL statements in a transaction.
337331 fn store_partial_paths_for_file_inner < ' a , IP > (
338- & mut self ,
332+ conn : & Connection ,
339333 graph : & StackGraph ,
340334 file : Handle < File > ,
341335 partials : & mut PartialPaths ,
@@ -345,11 +339,9 @@ impl SQLiteWriter {
345339 IP : IntoIterator < Item = & ' a PartialPath > ,
346340 {
347341 let file_str = graph[ file] . name ( ) ;
348- let mut node_stmt = self
349- . conn
350- . prepare_cached ( "INSERT INTO file_paths (file, local_id, json) VALUES (?, ?, ?)" ) ?;
351- let mut root_stmt = self
352- . conn
342+ let mut node_stmt =
343+ conn. prepare_cached ( "INSERT INTO file_paths (file, local_id, json) VALUES (?, ?, ?)" ) ?;
344+ let mut root_stmt = conn
353345 . prepare_cached ( "INSERT INTO root_paths (file, symbol_stack, json) VALUES (?, ?, ?)" ) ?;
354346 #[ cfg_attr( not( feature = "copious-debugging" ) , allow( unused) ) ]
355347 let mut node_path_count = 0usize ;
0 commit comments