xref: /aosp_15_r20/external/perfetto/src/trace_processor/sqlite/sql_stats_table.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2018 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/sqlite/sql_stats_table.h"
18 
19 #include <sqlite3.h>
20 #include <memory>
21 
22 #include "perfetto/base/logging.h"
23 #include "src/trace_processor/sqlite/bindings/sqlite_result.h"
24 #include "src/trace_processor/storage/trace_storage.h"
25 
26 namespace perfetto::trace_processor {
27 
Connect(sqlite3 * db,void * aux,int,const char * const *,sqlite3_vtab ** vtab,char **)28 int SqlStatsModule::Connect(sqlite3* db,
29                             void* aux,
30                             int,
31                             const char* const*,
32                             sqlite3_vtab** vtab,
33                             char**) {
34   static constexpr char kSchema[] = R"(
35     CREATE TABLE x(
36       query TEXT,
37       started BIGINT,
38       first_next BIGINT,
39       ended BIGINT,
40       PRIMARY KEY(started)
41     ) WITHOUT ROWID
42   )";
43   if (int ret = sqlite3_declare_vtab(db, kSchema); ret != SQLITE_OK) {
44     return ret;
45   }
46   std::unique_ptr<Vtab> res = std::make_unique<Vtab>();
47   res->storage = GetContext(aux);
48   *vtab = res.release();
49   return SQLITE_OK;
50 }
51 
Disconnect(sqlite3_vtab * vtab)52 int SqlStatsModule::Disconnect(sqlite3_vtab* vtab) {
53   delete GetVtab(vtab);
54   return SQLITE_OK;
55 }
56 
BestIndex(sqlite3_vtab *,sqlite3_index_info *)57 int SqlStatsModule::BestIndex(sqlite3_vtab*, sqlite3_index_info*) {
58   return SQLITE_OK;
59 }
60 
Open(sqlite3_vtab * raw_vtab,sqlite3_vtab_cursor ** cursor)61 int SqlStatsModule::Open(sqlite3_vtab* raw_vtab, sqlite3_vtab_cursor** cursor) {
62   std::unique_ptr<Cursor> c = std::make_unique<Cursor>();
63   c->storage = GetVtab(raw_vtab)->storage;
64   *cursor = c.release();
65   return SQLITE_OK;
66 }
67 
Close(sqlite3_vtab_cursor * cursor)68 int SqlStatsModule::Close(sqlite3_vtab_cursor* cursor) {
69   delete GetCursor(cursor);
70   return SQLITE_OK;
71 }
72 
Filter(sqlite3_vtab_cursor * cursor,int,const char *,int,sqlite3_value **)73 int SqlStatsModule::Filter(sqlite3_vtab_cursor* cursor,
74                            int,
75                            const char*,
76                            int,
77                            sqlite3_value**) {
78   auto* c = GetCursor(cursor);
79   c->row = 0;
80   c->num_rows = c->storage->sql_stats().size();
81   return SQLITE_OK;
82 }
83 
Next(sqlite3_vtab_cursor * cursor)84 int SqlStatsModule::Next(sqlite3_vtab_cursor* cursor) {
85   GetCursor(cursor)->row++;
86   return SQLITE_OK;
87 }
88 
Eof(sqlite3_vtab_cursor * cursor)89 int SqlStatsModule::Eof(sqlite3_vtab_cursor* cursor) {
90   auto* c = GetCursor(cursor);
91   return c->row >= c->num_rows;
92 }
93 
Column(sqlite3_vtab_cursor * cursor,sqlite3_context * ctx,int N)94 int SqlStatsModule::Column(sqlite3_vtab_cursor* cursor,
95                            sqlite3_context* ctx,
96                            int N) {
97   auto* c = GetCursor(cursor);
98   const TraceStorage::SqlStats& stats = c->storage->sql_stats();
99   switch (N) {
100     case Column::kQuery:
101       sqlite::result::StaticString(ctx, stats.queries()[c->row].c_str());
102       break;
103     case Column::kTimeStarted:
104       sqlite::result::Long(ctx, stats.times_started()[c->row]);
105       break;
106     case Column::kTimeFirstNext:
107       sqlite::result::Long(ctx, stats.times_first_next()[c->row]);
108       break;
109     case Column::kTimeEnded:
110       sqlite::result::Long(ctx, stats.times_ended()[c->row]);
111       break;
112     default:
113       PERFETTO_FATAL("Unknown column %d", N);
114       break;
115   }
116   return SQLITE_OK;
117 }
118 
Rowid(sqlite3_vtab_cursor *,sqlite_int64 *)119 int SqlStatsModule::Rowid(sqlite3_vtab_cursor*, sqlite_int64*) {
120   return SQLITE_ERROR;
121 }
122 
123 }  // namespace perfetto::trace_processor
124