|  | /* | 
|  | * Copyright (C) 2022 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ | 
|  | #define SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ | 
|  |  | 
|  | #include "src/trace_processor/views/macros_internal.h" | 
|  |  | 
|  | namespace perfetto { | 
|  | namespace trace_processor { | 
|  |  | 
|  | // The below macros allow defining C++ views with minimal boilerplate. | 
|  | // | 
|  | // Suppose you want to define a view which joins two tables slice and track. | 
|  | // slice has columns: id, ts, dur and name, track_id | 
|  | // track has columns: id, name | 
|  | // | 
|  | // If we were to define this view in SQL, it would look as follows: | 
|  | // CREATE VIEW slice_with_track AS | 
|  | // SELECT | 
|  | //   slice.id AS id, | 
|  | //   slice.ts AS ts, | 
|  | //   slice.dur AS dur, | 
|  | //   slice.name AS name, | 
|  | //   slice.track_id AS track_id, | 
|  | //   track.name AS track_name | 
|  | // FROM slice | 
|  | // JOIN track ON track.id = slice.track_id; | 
|  | // | 
|  | // The corresponding C++ macro invocation would be: | 
|  | // #define PERFETTO_TP_SLICE_TRACK_VIEW_DEF(NAME, FROM, JOIN, COL, _) | 
|  | //   NAME(SliceWithTrackView, "slice_with_track") | 
|  | //   COL(id, slice, id) | 
|  | //   COL(ts, slice, ts) | 
|  | //   COL(dur, slice, dur) | 
|  | //   COL(name, slice, name) | 
|  | //   COL(track_id, slice, track_id) | 
|  | //   COL(track_name, track, name) | 
|  | //   FROM(SliceTable, slice) | 
|  | //   JOIN(TrackTable, track, id, slice, track_id, View::kIdAlwaysPresent) | 
|  | // PERFETTO_TP_DECLARE_VIEW(PERFETTO_TP_SLICE_TRACK_VIEW_DEF); | 
|  | // | 
|  | // And in a .cc file: | 
|  | // PERFETTO_TP_DEFINE_VIEW(SliceWithTrackView); | 
|  | // | 
|  | // A shorter (and less error prone) version of the syntax, can be used if you | 
|  | // want to expose all the columns from the slice table. This involves passing | 
|  | // the table defintion macro for the slice table to | 
|  | // PERFETTO_TP_VIEW_EXPORT_FROM_COLS along with the FCOL argument: #define | 
|  | // PERFETTO_TP_SLICE_TRACK_VIEW_DEF(NAME, FROM, JOIN, COL, FCOL) | 
|  | //   NAME(SliceWithTrackView, "slice_with_track") | 
|  | //   PERFETTO_TP_VIEW_EXPORT_FROM_COLS(PERFETTO_TP_SLICE_TABLE_DEF, FCOL) | 
|  | //   COL(track_name, track, name) | 
|  | //   FROM(SliceTable, slice) | 
|  | //   JOIN(TrackTable, track, id, slice, track_id, View::kIdAlwaysPresent) | 
|  | // PERFETTO_TP_DECLARE_VIEW(PERFETTO_TP_SLICE_TRACK_VIEW_DEF); | 
|  |  | 
|  | // The macro used to define C++ views. | 
|  | // See the top of the file for how this should be used. | 
|  | // | 
|  | // This macro takes one argument: the full definition of the table; the | 
|  | // definition is a function macro taking four arguments: | 
|  | // 1. NAME, a function macro taking two arguments: the name of the new class | 
|  | //    being defined and the name of the table when exposed to SQLite. | 
|  | // 2. FROM, a function macro taking 2 arguments: | 
|  | //      a) the class name of the "root" table of this view | 
|  | //      b) the name of this table for use in the JOIN and COL macros (see below) | 
|  | // 3. JOIN, a function macro taking 6 arguments: | 
|  | //      a) the class name of the table which will be joined into this view on | 
|  | //         the "right" side of the join. | 
|  | //      b) the unique name of this table for use in subsequent JOIN and COL | 
|  | //      c) the name of the column from the "right" side which will be joined | 
|  | //         with the "left" side column. | 
|  | //      d) the name of a previously introduced table (in a previous FROM | 
|  | //         or JOIN invocation) which will be the "left" side of the join | 
|  | //      e) the name of the column from the "left" side which will be joined with | 
|  | //         the "right" side column. | 
|  | //      f) a bit-mased composed of bitwise OR-ed flags from View::Flag or | 
|  | //         View::kNoFlag if no flags apply. | 
|  | //    This macro should be invoked as many times as there are tables to be | 
|  | //    joined into the view. | 
|  | // 4. COL, a function macro taking two or three parameters: | 
|  | //      a) the name of the column in the view | 
|  | //      b) the name of the table this column is created from | 
|  | //      c) the name of the column in the table this column is created from | 
|  | //    This macro should be invoked as many times as there are columns in the | 
|  | //    view. | 
|  | // 5. FCOL, an opaque macros which should be passed to | 
|  | //    PERFETTO_TP_VIEW_EXPORT_FROM_COLS if all the columns in the FROM table | 
|  | //    should be exposed in this view; see above for how this call should look | 
|  | //    like. | 
|  | #define PERFETTO_TP_DECLARE_VIEW(DEF)                            \ | 
|  | PERFETTO_TP_VIEW_INTERNAL(                                     \ | 
|  | PERFETTO_TP_VIEW_NAME(DEF, PERFETTO_TP_VIEW_NAME_EXTRACT), \ | 
|  | PERFETTO_TP_VIEW_NAME(DEF, PERFETTO_TP_VIEW_CLASS_EXTRACT), DEF) | 
|  |  | 
|  | // Macro used to automatically expose all the columns in the FROM table | 
|  | // in a view. | 
|  | // See the top of the file for how this should be used. | 
|  | #define PERFETTO_TP_VIEW_EXPORT_FROM_COLS(DEF, FCOL) \ | 
|  | FCOL(from_table::Id, id)                           \ | 
|  | FCOL(StringPool::Id, type)                         \ | 
|  | PERFETTO_TP_ALL_COLUMNS(DEF, FCOL) | 
|  |  | 
|  | // Macro used to define destructors for C++ views. | 
|  | // See the top of the file for how this should be used. | 
|  | // | 
|  | // Should be invoked in a .cc file to prevent compiler errors about weak | 
|  | // vtables. | 
|  | #define PERFETTO_TP_DEFINE_VIEW(class_name) \ | 
|  | class_name::~class_name() = default;      \ | 
|  | class_name::QueryResult::~QueryResult() = default | 
|  |  | 
|  | }  // namespace trace_processor | 
|  | }  // namespace perfetto | 
|  |  | 
|  | #endif  // SRC_TRACE_PROCESSOR_VIEWS_MACROS_H_ |