blob: a8f330e9fa1ed338b2609d73aed5b1161f5f33bc [file] [log] [blame]
/*
* 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_