1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/prelude/functions/import.h"
18
19 #include <numeric>
20
21 #include "perfetto/base/status.h"
22 #include "perfetto/ext/base/string_utils.h"
23 #include "perfetto/ext/base/string_view.h"
24 #include "perfetto/trace_processor/basic_types.h"
25 #include "src/trace_processor/prelude/functions/create_function_internal.h"
26 #include "src/trace_processor/sqlite/scoped_db.h"
27 #include "src/trace_processor/sqlite/sqlite_table.h"
28 #include "src/trace_processor/sqlite/sqlite_utils.h"
29 #include "src/trace_processor/tp_metatrace.h"
30 #include "src/trace_processor/util/sql_modules.h"
31 #include "src/trace_processor/util/status_macros.h"
32
33 namespace perfetto {
34 namespace trace_processor {
35
Run(Import::Context * ctx,size_t argc,sqlite3_value ** argv,SqlValue &,Destructors &)36 base::Status Import::Run(Import::Context* ctx,
37 size_t argc,
38 sqlite3_value** argv,
39 SqlValue&,
40 Destructors&) {
41 if (argc != 1) {
42 return base::ErrStatus(
43 "IMPORT: invalid number of args; expected 1, received "
44 "%zu",
45 argc);
46 }
47 sqlite3_value* import_val = argv[0];
48
49 // Type check
50 {
51 base::Status status =
52 sqlite_utils::TypeCheckSqliteValue(import_val, SqlValue::Type::kString);
53 if (!status.ok()) {
54 return base::ErrStatus("IMPORT(%s): %s", sqlite3_value_text(import_val),
55 status.c_message());
56 }
57 }
58
59 const char* import_key =
60 reinterpret_cast<const char*>(sqlite3_value_text(import_val));
61
62 std::string module_name = sql_modules::GetModuleName(import_key);
63 auto module = ctx->modules->Find(module_name);
64 if (!module)
65 return base::ErrStatus("IMPORT: Unknown module name provided - %s",
66 import_key);
67
68 auto module_file = module->import_key_to_file.Find(import_key);
69 if (!module_file) {
70 return base::ErrStatus("IMPORT: Unknown filename provided - %s",
71 import_key);
72 }
73 // IMPORT is noop for already imported files.
74 if (module_file->imported) {
75 return base::OkStatus();
76 }
77
78 auto import_iter = ctx->tp->ExecuteQuery(module_file->sql);
79 if (import_iter.StatementWithOutputCount() > 0)
80 return base::ErrStatus("IMPORT: Imported file returning values.");
81 {
82 auto status = import_iter.Status();
83 if (!status.ok())
84 return base::ErrStatus("SQLite error on IMPORT: %s", status.c_message());
85 }
86
87 module_file->imported = true;
88 return base::OkStatus();
89 }
90
91 } // namespace trace_processor
92 } // namespace perfetto
93