1 /* 2 * Copyright (C) 2022 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 #ifndef SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ 18 #define SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ 19 20 #include "src/trace_processor/views/macros_internal.h" 21 22 namespace perfetto { 23 namespace trace_processor { 24 25 // The below macros allow defining C++ views with minimal boilerplate. 26 // 27 // Suppose you want to define a view which joins two tables slice and track. 28 // slice has columns: id, ts, dur and name, track_id 29 // track has columns: id, name 30 // 31 // If we were to define this view in SQL, it would look as follows: 32 // CREATE VIEW slice_with_track AS 33 // SELECT 34 // slice.id AS id, 35 // slice.ts AS ts, 36 // slice.dur AS dur, 37 // slice.name AS name, 38 // slice.track_id AS track_id, 39 // track.name AS track_name 40 // FROM slice 41 // JOIN track ON track.id = slice.track_id; 42 // 43 // The corresponding C++ macro invocation would be: 44 // #define PERFETTO_TP_SLICE_TRACK_VIEW_DEF(NAME, FROM, JOIN, COL, _) 45 // NAME(SliceWithTrackView, "slice_with_track") 46 // COL(id, slice, id) 47 // COL(ts, slice, ts) 48 // COL(dur, slice, dur) 49 // COL(name, slice, name) 50 // COL(track_id, slice, track_id) 51 // COL(track_name, track, name) 52 // FROM(SliceTable, slice) 53 // JOIN(TrackTable, track, id, slice, track_id, View::kIdAlwaysPresent) 54 // PERFETTO_TP_DECLARE_VIEW(PERFETTO_TP_SLICE_TRACK_VIEW_DEF); 55 // 56 // And in a .cc file: 57 // PERFETTO_TP_DEFINE_VIEW(SliceWithTrackView); 58 // 59 // A shorter (and less error prone) version of the syntax, can be used if you 60 // want to expose all the columns from the slice table. This involves passing 61 // the table defintion macro for the slice table to 62 // PERFETTO_TP_VIEW_EXPORT_FROM_COLS along with the FCOL argument: #define 63 // PERFETTO_TP_SLICE_TRACK_VIEW_DEF(NAME, FROM, JOIN, COL, FCOL) 64 // NAME(SliceWithTrackView, "slice_with_track") 65 // PERFETTO_TP_VIEW_EXPORT_FROM_COLS(PERFETTO_TP_SLICE_TABLE_DEF, FCOL) 66 // COL(track_name, track, name) 67 // FROM(SliceTable, slice) 68 // JOIN(TrackTable, track, id, slice, track_id, View::kIdAlwaysPresent) 69 // PERFETTO_TP_DECLARE_VIEW(PERFETTO_TP_SLICE_TRACK_VIEW_DEF); 70 71 // The macro used to define C++ views. 72 // See the top of the file for how this should be used. 73 // 74 // This macro takes one argument: the full definition of the table; the 75 // definition is a function macro taking four arguments: 76 // 1. NAME, a function macro taking two arguments: the name of the new class 77 // being defined and the name of the table when exposed to SQLite. 78 // 2. FROM, a function macro taking 2 arguments: 79 // a) the class name of the "root" table of this view 80 // b) the name of this table for use in the JOIN and COL macros (see below) 81 // 3. JOIN, a function macro taking 6 arguments: 82 // a) the class name of the table which will be joined into this view on 83 // the "right" side of the join. 84 // b) the unique name of this table for use in subsequent JOIN and COL 85 // c) the name of the column from the "right" side which will be joined 86 // with the "left" side column. 87 // d) the name of a previously introduced table (in a previous FROM 88 // or JOIN invocation) which will be the "left" side of the join 89 // e) the name of the column from the "left" side which will be joined with 90 // the "right" side column. 91 // f) a bit-mased composed of bitwise OR-ed flags from View::Flag or 92 // View::kNoFlag if no flags apply. 93 // This macro should be invoked as many times as there are tables to be 94 // joined into the view. 95 // 4. COL, a function macro taking two or three parameters: 96 // a) the name of the column in the view 97 // b) the name of the table this column is created from 98 // c) the name of the column in the table this column is created from 99 // This macro should be invoked as many times as there are columns in the 100 // view. 101 // 5. FCOL, an opaque macros which should be passed to 102 // PERFETTO_TP_VIEW_EXPORT_FROM_COLS if all the columns in the FROM table 103 // should be exposed in this view; see above for how this call should look 104 // like. 105 #define PERFETTO_TP_DECLARE_VIEW(DEF) \ 106 PERFETTO_TP_VIEW_INTERNAL( \ 107 PERFETTO_TP_VIEW_NAME(DEF, PERFETTO_TP_VIEW_NAME_EXTRACT), \ 108 PERFETTO_TP_VIEW_NAME(DEF, PERFETTO_TP_VIEW_CLASS_EXTRACT), DEF) 109 110 // Macro used to automatically expose all the columns in the FROM table 111 // in a view. 112 // See the top of the file for how this should be used. 113 #define PERFETTO_TP_VIEW_EXPORT_FROM_COLS(DEF, FCOL) \ 114 FCOL(from_table::Id, id) \ 115 FCOL(StringPool::Id, type) \ 116 PERFETTO_TP_ALL_COLUMNS(DEF, FCOL) 117 118 // Macro used to define destructors for C++ views. 119 // See the top of the file for how this should be used. 120 // 121 // Should be invoked in a .cc file to prevent compiler errors about weak 122 // vtables. 123 #define PERFETTO_TP_DEFINE_VIEW(class_name) \ 124 class_name::~class_name() = default; \ 125 class_name::QueryResult::~QueryResult() = default 126 127 } // namespace trace_processor 128 } // namespace perfetto 129 130 #endif // SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ 131