You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
4.5 KiB
110 lines
4.5 KiB
7 years ago
|
(*
|
||
|
* Copyright (c) 2018 - present Facebook, Inc.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* This source code is licensed under the BSD style license found in the
|
||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||
|
*)
|
||
|
open! IStd
|
||
7 years ago
|
module L = Logging
|
||
7 years ago
|
|
||
7 years ago
|
let store_statement =
|
||
|
ResultsDatabase.register_statement
|
||
|
{|
|
||
|
INSERT OR REPLACE INTO source_files
|
||
|
VALUES (:source, :cfgs, :tenv, :proc_names, :freshly_captured) |}
|
||
|
|
||
|
|
||
|
let add source_file cfg tenv =
|
||
|
Cfg.inline_java_synthetic_methods cfg ;
|
||
|
(* NOTE: it's important to write attribute files to disk before writing cfgs to disk.
|
||
|
OndemandCapture module relies on it - it uses existance of the cfg as a barrier to make
|
||
|
sure that all attributes were written to disk (but not necessarily flushed) *)
|
||
|
Cfg.save_attributes source_file cfg ;
|
||
|
ResultsDatabase.with_registered_statement store_statement ~f:(fun db store_stmt ->
|
||
|
SourceFile.SQLite.serialize source_file |> Sqlite3.bind store_stmt 1
|
||
|
(* :source *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"store bind source file" ;
|
||
|
Cfg.SQLite.serialize cfg |> Sqlite3.bind store_stmt 2
|
||
|
(* :cfg *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"store bind cfg" ;
|
||
|
Tenv.SQLite.serialize tenv |> Sqlite3.bind store_stmt 3
|
||
|
(* :tenv *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"store bind type environment" ;
|
||
|
Cfg.get_all_proc_names cfg |> Typ.Procname.SQLiteList.serialize |> Sqlite3.bind store_stmt 4
|
||
|
(* :proc_names *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"store bind proc names" ;
|
||
|
Sqlite3.bind store_stmt 5 (Sqlite3.Data.INT Int64.one)
|
||
|
(* :freshly_captured *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"store freshness" ;
|
||
|
SqliteUtils.sqlite_unit_step ~finalize:false ~log:"Cfg.store" db store_stmt )
|
||
|
|
||
|
|
||
7 years ago
|
let get_all () =
|
||
|
let db = ResultsDatabase.get_database () in
|
||
|
Sqlite3.prepare db "SELECT source_file FROM source_files"
|
||
|
|> SqliteUtils.sqlite_result_rev_list_step db ~log:"getting all source files"
|
||
|
|> List.filter_map ~f:(Option.map ~f:SourceFile.SQLite.deserialize)
|
||
|
|
||
|
|
||
7 years ago
|
let load_proc_names_statement =
|
||
|
ResultsDatabase.register_statement
|
||
|
"SELECT procedure_names FROM source_files WHERE source_file = :k"
|
||
|
|
||
|
|
||
|
let proc_names_of_source source =
|
||
|
ResultsDatabase.with_registered_statement load_proc_names_statement ~f:(fun db load_stmt ->
|
||
|
SourceFile.SQLite.serialize source |> Sqlite3.bind load_stmt 1
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"load bind source file" ;
|
||
|
SqliteUtils.sqlite_result_step ~finalize:false db ~log:"SourceFiles.proc_names_of_source"
|
||
|
load_stmt
|
||
|
|> Option.value_map ~default:[] ~f:Typ.Procname.SQLiteList.deserialize )
|
||
|
|
||
|
|
||
7 years ago
|
let exists_source_statement =
|
||
7 years ago
|
ResultsDatabase.register_statement "SELECT 1 FROM source_files WHERE source_file = :k"
|
||
|
|
||
|
|
||
|
let is_captured source =
|
||
7 years ago
|
ResultsDatabase.with_registered_statement exists_source_statement ~f:(fun db exists_stmt ->
|
||
7 years ago
|
SourceFile.SQLite.serialize source |> Sqlite3.bind exists_stmt 1
|
||
|
(* :k *)
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"load captured source file" ;
|
||
|
SqliteUtils.sqlite_result_step ~finalize:false ~log:"SourceFiles.is_captured" db exists_stmt
|
||
|
|> Option.is_some )
|
||
7 years ago
|
|
||
|
|
||
|
let is_non_empty_statement =
|
||
|
ResultsDatabase.register_statement "SELECT 1 FROM source_files LIMIT 1"
|
||
|
|
||
|
|
||
|
let is_empty () =
|
||
|
ResultsDatabase.with_registered_statement is_non_empty_statement ~f:(fun db stmt ->
|
||
|
SqliteUtils.sqlite_result_step ~finalize:false ~log:"SourceFiles.is_empty" db stmt
|
||
|
|> Option.is_none )
|
||
|
|
||
|
|
||
|
let is_freshly_captured_statement =
|
||
|
ResultsDatabase.register_statement
|
||
|
"SELECT freshly_captured FROM source_files WHERE source_file = :k"
|
||
|
|
||
|
|
||
|
let is_freshly_captured source =
|
||
|
ResultsDatabase.with_registered_statement is_freshly_captured_statement ~f:(fun db load_stmt ->
|
||
|
SourceFile.SQLite.serialize source |> Sqlite3.bind load_stmt 1
|
||
|
|> SqliteUtils.check_sqlite_error db ~log:"load bind source file" ;
|
||
|
SqliteUtils.sqlite_result_step ~finalize:false ~log:"SourceFiles.is_freshly_captured" db
|
||
|
load_stmt
|
||
|
|> Option.value_map ~default:false ~f:(function [@warning "-8"] Sqlite3.Data.INT p ->
|
||
|
Int64.equal p Int64.one ) )
|
||
|
|
||
|
|
||
|
let mark_all_stale_statement =
|
||
|
ResultsDatabase.register_statement "UPDATE source_files SET freshly_captured = 0"
|
||
|
|
||
|
|
||
|
let mark_all_stale () =
|
||
|
ResultsDatabase.with_registered_statement mark_all_stale_statement ~f:(fun db stmt ->
|
||
|
SqliteUtils.sqlite_unit_step db ~finalize:false ~log:"mark_all_stale" stmt )
|