trace_processor_shell: Also export views to SQLite db

This patch makes the trace processor shell also export SQL views to a
dumped SQLite database. This makes it easier to work with exported data
since it will be similar to what the shell and UI present.

Bug: 149999382
Change-Id: Id244089a2ac78447404675937ff0d9ec27b3ab7b
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 28e7f15..a08c609 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -245,6 +245,7 @@
     return 1;
   }
 
+  // Export real and virtual tables.
   auto tables_it = g_tp->ExecuteQuery(
       "SELECT name FROM perfetto_tables UNION "
       "SELECT name FROM sqlite_master WHERE type='table'");
@@ -270,6 +271,34 @@
     return 1;
   }
 
+  // Export views.
+  auto views_it =
+      g_tp->ExecuteQuery("SELECT sql FROM sqlite_master WHERE type='view'");
+  for (uint32_t rows = 0; views_it.Next(); rows++) {
+    std::string sql = views_it.Get(0).string_value;
+    // View statements are of the form "CREATE VIEW name AS stmt". We need to
+    // rewrite name to point to the exported db.
+    const std::string kPrefix = "CREATE VIEW ";
+    PERFETTO_CHECK(sql.find(kPrefix) == 0);
+    sql = sql.substr(0, kPrefix.size()) + "perfetto_export." +
+          sql.substr(kPrefix.size());
+
+    auto export_it = g_tp->ExecuteQuery(sql);
+    bool export_has_more = export_it.Next();
+    PERFETTO_DCHECK(!export_has_more);
+
+    status = export_it.Status();
+    if (!status.ok()) {
+      PERFETTO_ELOG("SQLite error: %s", status.c_message());
+      return 1;
+    }
+  }
+  status = views_it.Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("SQLite error: %s", status.c_message());
+    return 1;
+  }
+
   auto detach_it = g_tp->ExecuteQuery("DETACH DATABASE perfetto_export");
   bool detach_has_more = attach_it.Next();
   PERFETTO_DCHECK(!detach_has_more);