@ -7,7 +7,8 @@
open ! IStd
let attribute_replace_statement =
module Implementation = struct
let attribute_replace_statement =
(* The innermost SELECT returns either the current attributes_kind and source_file associated with
the given proc name , or default values of ( - 1 , " " ) . These default values have the property that
they are always " less than " any legit value . More precisely , MAX ensures that some value is
@ -40,8 +41,9 @@ let attribute_replace_statement =
| }
let replace_attributes ~ pname_str ~ pname ~ akind ~ source_file ~ attributes ~ proc_desc ~ callees =
ResultsDatabase . with_registered_statement attribute_replace_statement ~ f : ( fun db replace_stmt ->
let replace_attributes ~ pname_str ~ pname ~ akind ~ source_file ~ attributes ~ proc_desc ~ callees =
ResultsDatabase . with_registered_statement attribute_replace_statement
~ f : ( fun db replace_stmt ->
Sqlite3 . bind replace_stmt 1 (* :pname *) pname
| > SqliteUtils . check_result_code db ~ log : " replace bind pname " ;
Sqlite3 . bind replace_stmt 2 (* :proc_name_hum *) ( Sqlite3 . Data . TEXT pname_str )
@ -59,7 +61,7 @@ let replace_attributes ~pname_str ~pname ~akind ~source_file ~attributes ~proc_d
SqliteUtils . result_unit db ~ finalize : false ~ log : " Attributes.replace " replace_stmt )
let source_file_store_statement =
let source_file_store_statement =
ResultsDatabase . register_statement
{ |
INSERT OR REPLACE INTO source_files
@ -67,7 +69,7 @@ let source_file_store_statement =
| }
let add_source_file ~ source_file ~ tenv ~ integer_type_widths ~ proc_names =
let add_source_file ~ source_file ~ tenv ~ integer_type_widths ~ proc_names =
ResultsDatabase . with_registered_statement source_file_store_statement ~ f : ( fun db store_stmt ->
Sqlite3 . bind store_stmt 1 source_file
(* :source *)
@ -87,16 +89,16 @@ let add_source_file ~source_file ~tenv ~integer_type_widths ~proc_names =
SqliteUtils . result_unit ~ finalize : false ~ log : " Cfg.store " db store_stmt )
let mark_all_source_files_stale_statement =
let mark_all_source_files_stale_statement =
ResultsDatabase . register_statement " UPDATE source_files SET freshly_captured = 0 "
let mark_all_source_files_stale () =
let mark_all_source_files_stale () =
ResultsDatabase . with_registered_statement mark_all_source_files_stale_statement
~ f : ( fun db stmt -> SqliteUtils . result_unit db ~ finalize : false ~ log : " mark_all_stale " stmt )
let merge_procedures_table ~ db_file =
let merge_procedures_table ~ db_file =
let db = ResultsDatabase . get_database () in
(* Do the merge purely in SQL for great speed. The query works by doing a left join between the
sub - table and the main one , and applying the same " more defined " logic as in Attributes in the
@ -119,7 +121,7 @@ let merge_procedures_table ~db_file =
~ log : ( Printf . sprintf " copying procedures of database '%s' " db_file )
let merge_source_files_table ~ db_file =
let merge_source_files_table ~ db_file =
let db = ResultsDatabase . get_database () in
Sqlite3 . exec db
{ |
@ -131,18 +133,71 @@ let merge_source_files_table ~db_file =
~ log : ( Printf . sprintf " copying source_files of database '%s' " db_file )
let merge_dbs ~ infer_out_src =
let merge_dbs ~ infer_out_src =
let db_file = infer_out_src ^/ ResultsDatabase . database_filename in
let main_db = ResultsDatabase . get_database () in
Sqlite3 . exec main_db ( Printf . sprintf " ATTACH '%s' AS attached " db_file )
| > SqliteUtils . check_result_code main_db ~ log : ( Printf . sprintf " attaching database '%s' " db_file ) ;
| > SqliteUtils . check_result_code main_db
~ log : ( Printf . sprintf " attaching database '%s' " db_file ) ;
merge_procedures_table ~ db_file ;
merge_source_files_table ~ db_file ;
Sqlite3 . exec main_db " DETACH attached "
| > SqliteUtils . check_result_code main_db ~ log : ( Printf . sprintf " detaching database '%s' " db_file ) ;
| > SqliteUtils . check_result_code main_db
~ log : ( Printf . sprintf " detaching database '%s' " db_file ) ;
()
let canonicalize () =
let canonicalize () =
let db = ResultsDatabase . get_database () in
SqliteUtils . exec db ~ log : " running VACUUM " ~ stmt : " VACUUM "
end
module Command = struct
type t =
| ReplaceAttributes of
{ pname_str : string
; pname : Sqlite3 . Data . t
; akind : int64
; source_file : Sqlite3 . Data . t
; attributes : Sqlite3 . Data . t
; proc_desc : Sqlite3 . Data . t
; callees : Sqlite3 . Data . t }
| AddSourceFile of
{ source_file : Sqlite3 . Data . t
; tenv : Sqlite3 . Data . t
; integer_type_widths : Sqlite3 . Data . t
; proc_names : Sqlite3 . Data . t }
| MarkAllSourceFilesStale
| MergeDBs of { infer_out_src : string }
| Vacuum
let execute = function
| ReplaceAttributes { pname_str ; pname ; akind ; source_file ; attributes ; proc_desc ; callees } ->
Implementation . replace_attributes ~ pname_str ~ pname ~ akind ~ source_file ~ attributes
~ proc_desc ~ callees
| AddSourceFile { source_file ; tenv ; integer_type_widths ; proc_names } ->
Implementation . add_source_file ~ source_file ~ tenv ~ integer_type_widths ~ proc_names
| MarkAllSourceFilesStale ->
Implementation . mark_all_source_files_stale ()
| MergeDBs { infer_out_src } ->
Implementation . merge_dbs ~ infer_out_src
| Vacuum ->
Implementation . canonicalize ()
end
let perform cmd = Command . execute cmd
let replace_attributes ~ pname_str ~ pname ~ akind ~ source_file ~ attributes ~ proc_desc ~ callees =
Command . ReplaceAttributes { pname_str ; pname ; akind ; source_file ; attributes ; proc_desc ; callees }
| > perform
let add_source_file ~ source_file ~ tenv ~ integer_type_widths ~ proc_names =
Command . AddSourceFile { source_file ; tenv ; integer_type_widths ; proc_names } | > perform
let mark_all_source_files_stale () = perform Command . MarkAllSourceFilesStale
let merge_dbs ~ infer_out_src = Command . MergeDBs { infer_out_src } | > perform
let canonicalize () = perform Command . Vacuum