[sqlite] skeleton protocol for dbwriter

Summary: Developing the Sqlite-writer process further, a type `command` is introduced, which will used for sending instructions down a communications channel to the daemon.  For now, the commands are interpreted locally.

Reviewed By: skcho

Differential Revision: D16985056

fbshipit-source-id: 2aa20908d
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent 83aea33c68
commit 26823b22f1

@ -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

Loading…
Cancel
Save