osquery-1/osquery/sql/dynamic_table_row.h
Jonathan Keljo 1870fd86d8 Introduce TableRow interface
Summary:
Continuing to march toward low-overhead, type-safe table rows, this commit
changes `TableRow` to be an interface rather than simply an alias for `Row`.
Accordingly, `DynamicTableRow` becomes an implementation of that interface
backed by a `Row`. The few remaining pieces of code that treated `TableRow`s as
`Row`s now call methods on the `TableRow` interface. Subsequent commits will
add code generation for strongly-typed table-specific implementations of
`TableRow`.

(Adapted from https://github.com/facebook/osquery/pull/5198)

Reviewed By: guliashvili

Differential Revision: D13438015

fbshipit-source-id: 61d5547e878e519c9706f94f844aab9d3e553410
2019-01-09 13:50:15 -08:00

97 lines
3.0 KiB
C++

/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the Apache 2.0 license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#pragma once
#include <osquery/core/sql/table_row.h>
#include <osquery/core/sql/table_rows.h>
#include <osquery/utils/json.h>
namespace osquery {
/** A TableRow backed by a string map. */
class DynamicTableRow : public TableRow {
public:
DynamicTableRow() : row() {}
DynamicTableRow(Row&& r) : row(std::move(r)) {}
DynamicTableRow(
std::initializer_list<std::pair<const std::string, std::string>> init)
: row(init) {}
DynamicTableRow(const DynamicTableRow&) = delete;
DynamicTableRow& operator=(const DynamicTableRow&) = delete;
explicit operator Row() const {
return row;
}
virtual int get_rowid(sqlite_int64 default_value, sqlite_int64* pRowid) const;
virtual int get_column(sqlite3_context* ctx, sqlite3_vtab* pVtab, int col);
virtual Status serialize(JSON& doc, rapidjson::Value& obj) const;
virtual TableRowHolder clone() const;
inline std::string& operator[](const std::string& key) {
return row[key];
}
inline std::string& operator[](std::string&& key) {
return row[key];
}
inline size_t count(const std::string& key) const {
return row.count(key);
}
private:
Row row;
};
/// Syntactic sugar making DynamicRows inside of TableRowHolders easier to work
/// with. This should go away once strongly typed rows are used everywhere.
class DynamicTableRowHolder {
public:
DynamicTableRowHolder() : row(new DynamicTableRow()), ptr(row) {}
DynamicTableRowHolder(
std::initializer_list<std::pair<const std::string, std::string>> init)
: row(new DynamicTableRow(init)), ptr(row) {}
inline operator TableRowHolder &&() {
return std::move(ptr);
}
inline std::string& operator[](const std::string& key) {
return (*row)[key];
}
inline std::string& operator[](std::string&& key) {
return (*row)[key];
}
inline size_t count(const std::string& key) {
return (*row).count(key);
}
private:
DynamicTableRow* row;
TableRowHolder ptr;
};
inline DynamicTableRowHolder make_table_row() {
return DynamicTableRowHolder();
}
inline DynamicTableRowHolder make_table_row(
std::initializer_list<std::pair<const std::string, std::string>> init) {
return DynamicTableRowHolder(init);
}
/// Converts a QueryData struct to TableRows. Intended for use only in
/// generated code.
TableRows tableRowsFromQueryData(QueryData&& rows);
/**
* @brief Deserialize a DynamicTableRow object from JSON object.
*
* @param obj the input JSON value (should be an object).
* @param r [output] the output DynamicTableRowHolder structure.
*
* @return Status indicating the success or failure of the operation.
*/
Status deserializeRow(const rapidjson::Value& doc, DynamicTableRowHolder& r);
} // namespace osquery