• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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