TEST_F(VirtualTableTests, test_table_cache) { // Get a database connection. Registry::add<cacheTablePlugin>("table", "cache"); auto dbc = SQLiteDBManager::getUnique(); { auto cache = std::make_shared<cacheTablePlugin>(); attachTableInternal("cache", cache->columnDefinition(), dbc); } QueryData results; // Run a query with a join within. std::string statement = "SELECT c2.data as data FROM cache c1, cache c2;"; auto status = queryInternal(statement, results, dbc->db()); dbc->clearAffectedTables(); EXPECT_TRUE(status.ok()); ASSERT_EQ(results.size(), 1U); EXPECT_EQ(results[0]["data"], "more_awesome_data"); // Run the query again, the virtual table cache should have been expired. results.clear(); statement = "SELECT data from cache c1"; queryInternal(statement, results, dbc->db()); ASSERT_EQ(results.size(), 1U); ASSERT_EQ(results[0]["data"], "awesome_data"); }
SQLInternal::SQLInternal(const std::string& q) { auto dbc = SQLiteDBManager::get(); status_ = queryInternal(q, results_, dbc->db()); // One of the advantages of using SQLInternal (aside from the Registry-bypass) // is the ability to "deep-inspect" the table attributes and actions. event_based_ = (dbc->getAttributes() & TableAttributes::EVENT_BASED) != 0; dbc->clearAffectedTables(); }
TEST_F(SQLiteUtilTests, test_affected_tables) { auto dbc = getTestDBC(); QueryData results; auto status = queryInternal("SELECT * FROM time", results, dbc->db()); // Since the table scanned from "time", it should be recorded as affected. EXPECT_EQ(dbc->affected_tables_.count("time"), 1U); dbc->clearAffectedTables(); EXPECT_EQ(dbc->affected_tables_.size(), 0U); }
int profile(int argc, char *argv[]) { std::string query; if (!osquery::platformIsatty(stdin)) { std::getline(std::cin, query); } else if (argc < 2) { // No query input provided via stdin or as a positional argument. fprintf(stderr, "No query provided via stdin or args to profile...\n"); return 2; } else { query = std::string(argv[1]); } if (osquery::FLAGS_profile_delay > 0) { osquery::sleepFor(osquery::FLAGS_profile_delay * 1000); } // Perform some duplication from Initializer with respect to database setup. osquery::DatabasePlugin::setAllowOpen(true); osquery::Registry::setActive("database", "ephemeral"); auto dbc = osquery::SQLiteDBManager::get(); for (size_t i = 0; i < static_cast<size_t>(osquery::FLAGS_profile); ++i) { osquery::QueryData results; auto status = osquery::queryInternal(query, results, dbc->db()); dbc->clearAffectedTables(); if (!status) { fprintf(stderr, "Query failed (%d): %s\n", status.getCode(), status.what().c_str()); return status.getCode(); } } if (osquery::FLAGS_profile_delay > 0) { osquery::sleepFor(osquery::FLAGS_profile_delay); } return 0; }
Status SQLiteSQLPlugin::query(const std::string& q, QueryData& results) const { auto dbc = SQLiteDBManager::get(); auto result = queryInternal(q, results, dbc->db()); dbc->clearAffectedTables(); return result; }
SQLInternal::SQLInternal(const std::string& q) { auto dbc = SQLiteDBManager::get(); status_ = queryInternal(q, results_, dbc->db()); dbc->clearAffectedTables(); }