From 4f37abac1a8c77ee3a574e183d1841544c3f1c97 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Fri, 25 Mar 2016 20:04:15 +0900 Subject: [PATCH] add db module Change-Id: I55fc9a7a405d61d24c66368fdec4dc1c8b418c4d Signed-off-by: Dongsun Lee --- CMakeLists.txt | 2 + data/scripts/create_schema.sql | 17 ++ data/scripts/drop_all.sql | 5 + packaging/csr-framework.spec | 11 + src/CMakeLists.txt | 5 + src/framework/database/column.cpp | 76 ++++++ src/framework/database/column.h | 76 ++++++ src/framework/database/connection.cpp | 52 +++++ src/framework/database/connection.h | 72 ++++++ src/framework/database/csr_db.cpp | 423 ++++++++++++++++++++++++++++++++++ src/framework/database/csr_db.h | 88 +++++++ src/framework/database/statement.cpp | 236 +++++++++++++++++++ src/framework/database/statement.h | 85 +++++++ test/CMakeLists.txt | 10 + test/test-internal-database.cpp | 235 +++++++++++++++++++ 15 files changed, 1393 insertions(+) create mode 100644 data/scripts/create_schema.sql create mode 100644 data/scripts/drop_all.sql create mode 100644 src/framework/database/column.cpp create mode 100644 src/framework/database/column.h create mode 100644 src/framework/database/connection.cpp create mode 100644 src/framework/database/connection.h create mode 100644 src/framework/database/csr_db.cpp create mode 100644 src/framework/database/csr_db.h create mode 100644 src/framework/database/statement.cpp create mode 100644 src/framework/database/statement.h create mode 100644 test/test-internal-database.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c4fffd6..73f44d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,8 @@ STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") ADD_DEFINITIONS("-DSERVICE_NAME=\"${SERVICE_NAME}\"") ADD_DEFINITIONS("-DINCLUDE_INSTALL_DIR=\"${INCLUDE_INSTALL_DIR}\"") ADD_DEFINITIONS("-DBIN_DIR=\"${BIN_DIR}\"") +ADD_DEFINITIONS("-DRO_DBSPACE=\"${RO_DBSPACE}\"") +ADD_DEFINITIONS("-DRW_DBSPACE=\"${RW_DBSPACE}\"") ADD_DEFINITIONS("-DSAMPLE_ENGINE_WORKING_DIR=\"${SAMPLE_ENGINE_WORKING_DIR}\"") ADD_DEFINITIONS("-DTEST_DIR=\"${TEST_DIR}\"") diff --git a/data/scripts/create_schema.sql b/data/scripts/create_schema.sql new file mode 100644 index 0000000..9edf76d --- /dev/null +++ b/data/scripts/create_schema.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS SCHEMA_INFO(name TEXT PRIMARY KEY NOT NULL, + value TEXT); + +CREATE TABLE IF NOT EXISTS SCAN_REQUEST(dir TEXT PRIMARY KEY, + last_scan INTEGER NOT NULL, + data_version TEXT NOT NULL); + +CREATE TABLE IF NOT EXISTS DETECTED_MALWARE_FILE(path TEXT PRIMARY KEY NOT NULL, + data_version TEXT NOT NULL, + severity_level INTEGER NOT NULL, + threat_type INTEGER NOT NULL, + malware_name TEXT NOT NULL, + detailed_url TEXT, + detected_time INTEGER NOT NULL, + modified_time INTEGER NOT NULL, + ignored INTEGER NOT NULL); + diff --git a/data/scripts/drop_all.sql b/data/scripts/drop_all.sql new file mode 100644 index 0000000..9af2f06 --- /dev/null +++ b/data/scripts/drop_all.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS DETECTED_MALWARE_FILE; + +DROP TABLE IF EXISTS SCAN_REQUEST; + +DROP TABLE IF EXISTS SCHEMA_INFO; diff --git a/packaging/csr-framework.spec b/packaging/csr-framework.spec index 92e38dc..06a19bf 100644 --- a/packaging/csr-framework.spec +++ b/packaging/csr-framework.spec @@ -11,6 +11,7 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(sqlite3) Requires: lib%{name}-common = %{version}-%{release} %{?systemd_requires} @@ -22,6 +23,8 @@ file contents and checking url to prevent malicious items. %global bin_dir %{_bindir} %global sbin_dir /sbin %global ro_data_dir %{_datadir} +%global ro_db_dir %{_datadir}/%{service_name}/dbspace +%global rw_db_dir /opt/share//%{service_name}/dbspace %global sample_engine_working_dir /opt/share/%{service_name}/engine %global sample_engine_dir %{_libdir} %global test_dir /opt/share/%{service_name}-test @@ -82,6 +85,8 @@ test program of csr-framework -DBIN_DIR:PATH=%{bin_dir} \ -DSYSTEMD_UNIT_DIR=%{_unitdir} \ -DSYSTEMD_UNIT_USER_DIR=%{_unitdir_user} \ + -DRO_DBSPACE:PATH=%{ro_db_dir} \ + -DRW_DBSPACE:PATH=%{rw_db_dir} \ -DSAMPLE_ENGINE_WORKING_DIR:PATH=%{sample_engine_working_dir} \ -DSAMPLE_ENGINE_DIR:PATH=%{sample_engine_dir} \ -DTEST_DIR:PATH=%{test_dir} @@ -108,6 +113,10 @@ cp LICENSE %{buildroot}%{ro_data_dir}/license/lib%{name}-common cp LICENSE %{buildroot}%{ro_data_dir}/license/%{name}-test cp LICENSE.BSL-1.0 %{buildroot}%{ro_data_dir}/license/%{name}-test.BSL-1.0 +mkdir -p %{buildroot}%{ro_db_dir} +mkdir -p %{buildroot}%{rw_db_dir} +cp data/scripts/*.sql %{buildroot}%{ro_db_dir} + %post systemctl daemon-reload if [ $1 = 1 ]; then @@ -155,6 +164,8 @@ fi %{_unitdir}/sockets.target.wants/%{service_name}-popup.socket %{_unitdir}/%{service_name}-popup.socket +%attr(444, system, system) %{ro_db_dir}/*.sql + # sample engine related files %{sample_engine_dir}/lib%{service_name}-cs-engine.so %{sample_engine_dir}/lib%{service_name}-wp-engine.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4cce495..95d1e95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ PKG_CHECK_MODULES(${TARGET_CSR_SERVER}_DEP REQUIRED libsystemd-daemon + sqlite3 ) SET(${TARGET_CSR_SERVER}_SRCS @@ -32,6 +33,10 @@ SET(${TARGET_CSR_SERVER}_SRCS # question and response codes needed on both of # csr-server and popup-backend service framework/ui/common.cpp + framework/database/column.cpp + framework/database/connection.cpp + framework/database/statement.cpp + framework/database/csr_db.cpp ) INCLUDE_DIRECTORIES( diff --git a/src/framework/database/column.cpp b/src/framework/database/column.cpp new file mode 100644 index 0000000..58e0d89 --- /dev/null +++ b/src/framework/database/column.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 + */ + +#include + +#include "database/column.h" + +namespace Csr { + +namespace Database { + +Column::Column(const Statement &stmt, int idx) + : statement(stmt.get()), + index(idx) +{ +} + +Column::~Column() noexcept { +} + +std::string Column::getName() const +{ + return sqlite3_column_name(statement, index); +} + +int Column::getInt() const +{ + return sqlite3_column_int(statement, index); +} + +sqlite3_int64 Column::getInt64() const +{ + return sqlite3_column_int64(statement, index); +} + +double Column::getDouble() const +{ + return sqlite3_column_double(statement, index); +} + +const char *Column::getText() const +{ + return reinterpret_cast(sqlite3_column_text(statement, index)); +} + +const void *Column::getBlob() const +{ + return sqlite3_column_blob(statement, index); +} + +int Column::getType() const +{ + return sqlite3_column_type(statement, index); +} + +int Column::getBytes() const +{ + return sqlite3_column_bytes(statement, index); +} + +} // namespace Database + +} // namespace Csr diff --git a/src/framework/database/column.h b/src/framework/database/column.h new file mode 100644 index 0000000..be93ed5 --- /dev/null +++ b/src/framework/database/column.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __COLUMN__ +#define __COLUMN__ + +#include + +#include + +#include "database/statement.h" + +namespace Csr { + +namespace Database { + +class Column { +public: + Column(const Statement &stmt, int idx); + virtual ~Column() noexcept; + + std::string getName() const; + sqlite3_int64 getInt64() const; + const char *getText() const; + double getDouble() const; + const void *getBlob() const; + int getInt() const; + int getType() const; + int getBytes() const; + + inline int size() const { + return getBytes(); + } + + inline operator int() const { + return getInt(); + } + + inline operator sqlite3_int64() const { + return getInt64(); + } + + inline operator double() const { + return getDouble(); + } + + inline operator const char *() const { + return getText(); + } + + inline operator const void *() const { + return getBlob(); + } + +private: + sqlite3_stmt *statement; + int index; +}; + +} // namespace Database + +} // namespace Csr +#endif //__COLUMN__ diff --git a/src/framework/database/connection.cpp b/src/framework/database/connection.cpp new file mode 100644 index 0000000..ad45944 --- /dev/null +++ b/src/framework/database/connection.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 + */ + +#include +#include + + +#include "database/connection.h" + +namespace Csr { + +namespace Database { + +Connection::Connection(const std::string &name, const int flags) + : handle(nullptr), + filename(name) +{ + if (::sqlite3_open_v2(filename.c_str(), &handle, flags, NULL)) { + throw std::runtime_error(getErrorMessage()); + } +} + +Connection::~Connection() +{ + sqlite3_close(handle); +} + +int Connection::exec(const std::string &query) +{ + if (::sqlite3_exec(handle, query.c_str(), NULL, NULL, NULL) != SQLITE_OK) { + throw std::runtime_error(getErrorMessage()); + } + + return sqlite3_changes(handle); +} + +} // namespace Database + +} // namespace Csr diff --git a/src/framework/database/connection.h b/src/framework/database/connection.h new file mode 100644 index 0000000..45e6d8c --- /dev/null +++ b/src/framework/database/connection.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __DB_CONNECTION__ +#define __DB_CONNECTION__ + +#include + +#include + +namespace Csr { + +namespace Database { + +class Connection { +public: + enum Mode { + Create = SQLITE_OPEN_CREATE, + ReadWrite = SQLITE_OPEN_READWRITE + }; + + Connection(const std::string &name, const int flags); + virtual ~Connection(); + + int exec(const std::string &query); + + inline long long getLastInsertRowId() const noexcept { + return sqlite3_last_insert_rowid(handle); + } + + inline const std::string &getName() const noexcept { + return filename; + } + + inline int getErrorCode() const { + return sqlite3_errcode(handle); + } + + inline int getExtendedErrorCode() const { + return sqlite3_extended_errcode(handle); + } + + inline std::string getErrorMessage() const { + return sqlite3_errmsg(handle); + } + + inline sqlite3 *get() const noexcept { + return handle; + } + +private: + sqlite3 *handle; + std::string filename; +}; + +} // namespace Database + +} // namespace Csr +#endif //__DB_CONNECTION__ diff --git a/src/framework/database/csr_db.cpp b/src/framework/database/csr_db.cpp new file mode 100644 index 0000000..0a742f2 --- /dev/null +++ b/src/framework/database/csr_db.cpp @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 + */ + +#include +#include +#include + +#include "database/csr_db.h" +#include "database/connection.h" +#include "database/statement.h" +#include "database/column.h" + +namespace Csr { + +namespace Database { + +enum DBVersion : int { + DB_VERSION_1 = 1, + DB_VERSION_CURRENT = 1 +}; + +const char *SCRIPT_CREATE_SCHEMA = "create_schema"; +const char *SCRIPT_DROP_ALL_ITEMS = "drop_all"; +const char *SCRIPT_MIGRATE = "migrate_"; + +const std::string DB_VERSION_STR = "DB_VERSION"; + +//=========================================================================== +// Queries +//=========================================================================== + +const std::string QUERY_SEL_SCHEMA_INFO = + "select value from SCHEMA_INFO where name = ?"; + +const std::string QUERY_INS_SCHEMA_INFO = + "insert or replace into SCHEMA_INFO (name, value) values (?, ?)"; + + +const std::string QUERY_SEL_SCAN_REQUEST = + "select dir, last_scan from SCAN_REQUEST where dir = ? and data_version = ?"; + +const std::string QUERY_INS_SCAN_REQUEST = + "insert or replace into SCAN_REQUEST (dir, last_scan, data_version) " + "values (?, ?, ?)"; + +const std::string QUERY_DEL_SCAN_REQUEST_BY_DIR = + "delete from SCAN_REQUEST where dir = ?"; + +const std::string QUERY_DEL_SCAN_REQUEST = + "delete from SCAN_REQUEST "; + + +const std::string QUERY_SEL_DETECTED_BY_DIR = + "SELECT path, data_version, " + " severity_level, threat_type, malware_name, " + " detailed_url, detected_time, modified_time, ignored " + " FROM detected_malware_file where path like ? || '%' "; + +const std::string QUERY_SEL_DETECTED_BY_PATH = + "SELECT path, data_version, " + " severity_level, threat_type, malware_name, " + " detailed_url, detected_time, modified_time, ignored " + " FROM detected_malware_file where path = ? "; + +const std::string QUERY_INS_DETECTED = + "insert or replace into DETECTED_MALWARE_FILE " + " (path, data_version, severity_level, threat_type, malware_name, " + " detailed_url, detected_time, modified_time, ignored) " + " values (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + +const std::string QUERY_UPD_DETECTED_INGNORED = + "update DETECTED_MALWARE_FILE set ignored = ? where path = ?"; + +const std::string QUERY_DEL_DETECTED_BY_PATH = + "delete from DETECTED_MALWARE_FILE where path = ?"; + +const std::string QUERY_DEL_DETECTED_DEPRECATED = + "delete from DETECTED_MALWARE_FILE where path like ? || '%' " + " and data_version != ?"; + + +//=========================================================================== +// Constructor +//=========================================================================== + +CsrDB::CsrDB(const std::string &dbfile, const std::string &scriptsDirectory) + : conn(dbfile, Connection::Create | Connection::ReadWrite), scriptsDir(scriptsDirectory) +{ + initDatabase(); + conn.exec("VACUUM;"); +} + +CsrDB::~CsrDB() +{ +} + +//=========================================================================== +// SCHEMA_INFO table +//=========================================================================== + + +bool CsrDB::initDatabase() noexcept { + // run migration if old database is present + int schemaVersion; + if ((schemaVersion = getDbVersion()) <= 0 || schemaVersion > DB_VERSION_CURRENT) { + // DB empty or corrupted or too new scheme + // LogDebug("no database or database corrupted, initializing the DB"); + resetDatabase(); + } else if (schemaVersion < DB_VERSION_CURRENT) { + // migration needed + //LogDebug("DB migration from version " << schemaVersion << " to version " << DB_VERSION_CURRENT << " started."); + for (int vi = schemaVersion; vi < DB_VERSION_CURRENT; vi++) { + std::string script = getMigrationScript(vi); + if (script.size() <= 0) { + //LogWarn("script to migrate database from version: " << vi << + // " to version: " << vi+1 << " not available, resetting the DB"); + resetDatabase(); + break; + } + + //LogInfo("migrating from version " << vi << " to version " << vi+1); + if (!conn.exec(script.c_str())) { + //LogWarn("Error, migration database from version: " << vi << + // " to version: " << vi+1 << " failed, resetting the DB"); + resetDatabase(); + break; + } + } + // update DB version info + if (!setDbVersion(DB_VERSION_CURRENT)) { + //LogWarn("setting db version failed. version=: " << DB_VERSION_CURRENT <<", resetting the DB"); + resetDatabase(); + } + } + + return true; +} + +bool CsrDB::createSchema() noexcept { + try { + std::string script = getScript(SCRIPT_CREATE_SCHEMA); + if (script.size() <= 0) { + std::string errmsg = "Can not create the database schema: no initialization script"; + throw std::runtime_error(errmsg); + } + return conn.exec(script.c_str()); + } catch (std::exception &e) { + //LogWarn("createSchema failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::resetDatabase() noexcept { + try { + std::string script = getScript(SCRIPT_DROP_ALL_ITEMS); + if (script.size() <= 0) { + std::string errmsg = "Can not clear the database: no clearing script"; + throw std::runtime_error(errmsg); + } + conn.exec(script.c_str()); + return createSchema(); + } catch (std::exception &e) { + //LogWarn("resetDatabase failed.error_msg=" << e.what()); + return false; + } +} + +std::string CsrDB::getMigrationScript(int dbVersion) +{ + std::string scriptPath = std::string(SCRIPT_MIGRATE) + std::to_string(dbVersion); + return getScript(scriptPath); +} + +std::string CsrDB::getScript(std::string scriptName) +{ + std::string scriptPath = scriptsDir + std::string("/") + scriptName + std::string(".sql"); + std::ifstream is(scriptPath); + if (is.fail()) { + return std::string(); + } + std::istreambuf_iterator begin(is), end; + return std::string(begin, end); +} + +int CsrDB::getDbVersion() noexcept { + try{ + Statement stmt(conn, QUERY_SEL_SCHEMA_INFO); + + int idx = 0; + stmt.bind(++idx, DB_VERSION_STR); + + if (!stmt.step()) + return -1; + + return stmt.getColumn(0).getInt(); + } catch (std::exception &e) { + //LogWarn("getDbVersion failed.error_msg=" << e.what()); + return -1; + } +} + +bool CsrDB::setDbVersion(int version) noexcept { + try { + Statement stmt(conn, QUERY_INS_SCHEMA_INFO); + + int idx = 0; + stmt.bind(++idx, DB_VERSION_STR); + stmt.bind(++idx, version); + return stmt.exec(); + } catch (std::exception &e) { + //LogWarn("setDbVersion failed.error_msg=" << e.what()); + return false; + } +} + +//=========================================================================== +// SCAN_REQUEST table +//=========================================================================== + +long CsrDB::getLastScanTime(const std::string &dir, const std::string &dataVersion) noexcept { + try{ + Statement stmt(conn, QUERY_SEL_SCAN_REQUEST); + + int idx = 0; + stmt.bind(++idx, dir); + stmt.bind(++idx, dataVersion); + + if (!stmt.step()) + return -1; + + return static_cast(stmt.getColumn(1).getInt64()); + } catch (std::exception &e) { + //LogWarn("getLastScanTime failed.error_msg=" << e.what()); + return -1; + } +} + +bool CsrDB::insertLastScanTime(const std::string &dir, long scanTime, const std::string &dataVersion) noexcept { + try { + Statement stmt(conn, QUERY_INS_SCAN_REQUEST); + + int idx = 0; + stmt.bind(++idx, dir); + stmt.bind(++idx, static_cast(scanTime)); + stmt.bind(++idx, dataVersion); + return stmt.exec(); + } catch (std::exception &e) { + //LogWarn("insertLastScanTime failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::deleteLastScanTime(const std::string &dir) noexcept { + try { + Statement stmt(conn, QUERY_DEL_SCAN_REQUEST_BY_DIR); + + int idx = 0; + stmt.bind(++idx, dir); + stmt.exec(); + return true; // even if no rows are deleted + } catch (std::exception &e) { + //LogWarn("deleteLastScanTime failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::cleanLastScanTime() noexcept { + try { + Statement stmt(conn, QUERY_DEL_SCAN_REQUEST); + stmt.exec(); + return true; // even if no rows are deleted + } catch (std::exception &e) { + //LogWarn("cleanLastScanTime failed.error_msg=" << e.what()); + return false; + } +} + +//=========================================================================== +// DETECTED_MALWARE_FILE table +//=========================================================================== +DetectedListShrPtr CsrDB::getDetectedMalwares(const std::string &dir) noexcept { + DetectedListShrPtr detectedList = std::make_shared>(); + + try { + Statement stmt(conn, QUERY_SEL_DETECTED_BY_DIR); + + int idx = 0; + stmt.bind(++idx, dir); + + while (stmt.step()) { + DetectedShrPtr detected = std::make_shared(); + idx = -1; + detected->path = std::string(stmt.getColumn(++idx).getText()); + detected->dataVersion = std::string(stmt.getColumn(++idx).getText()); + detected->severityLevel = stmt.getColumn(++idx).getInt(); + detected->threatType = stmt.getColumn(++idx).getInt(); + detected->name = std::string(stmt.getColumn(++idx).getText()); + detected->detailedUrl = std::string(stmt.getColumn(++idx).getText()); + detected->detected_time = static_cast(stmt.getColumn(++idx).getInt64()); + detected->modified_time = static_cast(stmt.getColumn(++idx).getInt64()); + detected->ignored = stmt.getColumn(++idx).getInt(); + + detectedList->push_back(detected); + } + } catch (std::exception &e) { + //LogWarn("getDetectedMalwares failed.error_msg=" << e.what()); + } + return detectedList; +} + +DetectedShrPtr CsrDB::getDetectedMalware(const std::string &path) noexcept { + DetectedShrPtr detected = std::make_shared(); + + try { + Statement stmt(conn, QUERY_SEL_DETECTED_BY_PATH); + + int idx = 0; + stmt.bind(++idx, path); + + if (!stmt.step()) + return nullptr; + + idx = -1; + detected->path = std::string(stmt.getColumn(++idx).getText()); + detected->dataVersion = std::string(stmt.getColumn(++idx).getText()); + detected->severityLevel = stmt.getColumn(++idx).getInt(); + detected->threatType = stmt.getColumn(++idx).getInt(); + detected->name = std::string(stmt.getColumn(++idx).getText()); + detected->detailedUrl = std::string(stmt.getColumn(++idx).getText()); + detected->detected_time = static_cast(stmt.getColumn(++idx).getInt64()); + detected->modified_time = static_cast(stmt.getColumn(++idx).getInt64()); + detected->ignored = stmt.getColumn(++idx).getInt(); + + } catch (std::exception &e) { + //LogWarn("getDetectedMalware failed.error_msg=" << e.what()); + return nullptr; + } + return detected; +} + +bool CsrDB::insertDetectedMalware(const RowDetected &malware) noexcept { + try { + Statement stmt(conn, QUERY_INS_DETECTED); + + int idx = 0; + stmt.bind(++idx, malware.path); + stmt.bind(++idx, malware.dataVersion); + stmt.bind(++idx, malware.severityLevel); + stmt.bind(++idx, malware.threatType); + stmt.bind(++idx, malware.name); + stmt.bind(++idx, malware.detailedUrl); + stmt.bind(++idx, static_cast(malware.detected_time)); + stmt.bind(++idx, static_cast(malware.modified_time)); + stmt.bind(++idx, malware.ignored); + + return stmt.exec(); + } catch (std::exception &e) { + //LogWarn("insertDetectedMalware failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::setDetectedMalwareIgnored(const std::string &path, int ignored) noexcept { + try { + Statement stmt(conn, QUERY_UPD_DETECTED_INGNORED); + + int idx = 0; + stmt.bind(++idx, ignored); + stmt.bind(++idx, path); + + return stmt.exec(); + } catch (std::exception &e) { + //LogWarn("setDetectedMalwareIgnored failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::deleteDetecedMalware(const std::string &path) noexcept { + try { + Statement stmt(conn, QUERY_DEL_DETECTED_BY_PATH); + + int idx = 0; + stmt.bind(++idx, path); + stmt.exec(); + return true; // even if no rows are deleted + } catch (std::exception &e) { + //LogWarn("deleteDetecedMalware failed.error_msg=" << e.what()); + return false; + } +} + +bool CsrDB::deleteDeprecatedDetecedMalwares(const std::string &dir, const std::string &dataVersion) noexcept { + try { + Statement stmt(conn, QUERY_DEL_DETECTED_DEPRECATED); + + int idx = 0; + stmt.bind(++idx, dir); + stmt.bind(++idx, dataVersion); + stmt.exec(); + return true; // even if no rows are deleted + } catch (std::exception &e) { + //LogWarn("deleteDeprecatedDetecedMalwares failed.error_msg=" << e.what()); + return false; + } +} + + +}// namespace Database + +}// namespace Csr diff --git a/src/framework/database/csr_db.h b/src/framework/database/csr_db.h new file mode 100644 index 0000000..7a3a412 --- /dev/null +++ b/src/framework/database/csr_db.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 CONTENT_SCANNING_DB_HXX_ +#define CONTENT_SCANNING_DB_HXX_ + +#include +#include +#include + +#include "database/connection.h" + +namespace Csr { + +namespace Database { + +struct RowDetected { + std::string path; + std::string dataVersion; // engine's data version + int severityLevel; + int threatType; + std::string name; + std::string detailedUrl; + long detected_time; + long modified_time; + int ignored; + + RowDetected() : path(""), dataVersion(""), + severityLevel(-1), threatType(-1), + name(""), detailedUrl(""), detected_time(-1), + modified_time(-1), ignored(-1) {}; + ~RowDetected() {}; +}; + +typedef std::shared_ptr DetectedShrPtr; +typedef std::shared_ptr> DetectedListShrPtr; + +class CsrDB { +public: + CsrDB(const std::string &dbfile, const std::string &scriptsDir); + virtual ~CsrDB(); + + // SCHEMA_INFO + bool initDatabase() noexcept; + bool createSchema() noexcept; + bool resetDatabase() noexcept; + std::string getMigrationScript(int dbVersion); + std::string getScript(std::string scriptName); + int getDbVersion() noexcept; + bool setDbVersion(int version) noexcept; + + // SCAN_REQUEST + long getLastScanTime(const std::string &dir, const std::string &dataVersion) noexcept; + bool insertLastScanTime(const std::string &dir, long scanTime, const std::string &dataVersion) noexcept; + bool deleteLastScanTime(const std::string &dir) noexcept; + bool cleanLastScanTime() noexcept; + + // DETECTED_MALWARE_FILE & USER_RESPONSE + DetectedListShrPtr getDetectedMalwares(const std::string &dir) noexcept; + DetectedShrPtr getDetectedMalware(const std::string &path) noexcept; + bool insertDetectedMalware(const RowDetected &malware) noexcept; + bool setDetectedMalwareIgnored(const std::string &path, int userResponse) noexcept; + bool deleteDetecedMalware(const std::string &path) noexcept; + bool deleteDeprecatedDetecedMalwares(const std::string &dir, const std::string &dataVersion) noexcept; + +private: + Connection conn; + std::string scriptsDir; +}; + +}// namespace Database + + +}// namespace Csr +#endif /* CONTENT_SCANNING_DB_HXX_ */ diff --git a/src/framework/database/statement.cpp b/src/framework/database/statement.cpp new file mode 100644 index 0000000..68c49eb --- /dev/null +++ b/src/framework/database/statement.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 + */ + +#include +#include + +#include "database/connection.h" +#include "database/statement.h" +#include "database/column.h" + + +namespace Csr { + +namespace Database { + +Statement::Statement(const Connection &db, const std::string &query) + : statement(nullptr), + columnCount(0), + validRow(false) +{ + if (SQLITE_OK != ::sqlite3_prepare_v2(db.get(), + query.c_str(), + query.size(), + &statement, + NULL)) { + throw std::runtime_error(db.getErrorMessage()); + } + + columnCount = sqlite3_column_count(statement); +} + +Statement::~Statement() +{ + if (::sqlite3_finalize(statement) != SQLITE_OK) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::reset() +{ + if (::sqlite3_clear_bindings(statement) != SQLITE_OK) { + throw std::runtime_error(getErrorMessage()); + } + + if (::sqlite3_reset(statement) != SQLITE_OK) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::clearBindings() +{ + if (::sqlite3_clear_bindings(statement) != SQLITE_OK) { + throw std::runtime_error(getErrorMessage()); + } +} + +std::string Statement::getErrorMessage() const +{ + return ::sqlite3_errmsg(::sqlite3_db_handle(statement)); +} + +std::string Statement::getErrorMessage(int errorCode) const +{ + return ::sqlite3_errstr(errorCode); +} + +bool Statement::step() +{ + if (SQLITE_ROW == ::sqlite3_step(statement)) { + return (validRow = true); + } + + return (validRow = false); +} + +int Statement::exec() +{ + if (SQLITE_DONE == ::sqlite3_step(statement)) { + validRow = false; + } + + return sqlite3_changes(sqlite3_db_handle(statement)); +} + +Column Statement::getColumn(const int index) +{ + if (!validRow || (index >= columnCount)) { + throw std::runtime_error(getErrorMessage(SQLITE_RANGE)); + } + + return Column(*this, index); +} + +bool Statement::isNullColumn(const int index) const +{ + if (!validRow || (index >= columnCount)) { + throw std::runtime_error(getErrorMessage(SQLITE_RANGE)); + } + + return (SQLITE_NULL == sqlite3_column_type(statement, index)); +} + +std::string Statement::getColumnName(const int index) const +{ + if (index >= columnCount) { + throw std::runtime_error(getErrorMessage(SQLITE_RANGE)); + } + + return sqlite3_column_name(statement, index); +} + + +void Statement::bind(const int index, const int &value) +{ + if (SQLITE_OK != ::sqlite3_bind_int(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const int index, const sqlite3_int64 &value) +{ + if (SQLITE_OK != ::sqlite3_bind_int64(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const int index, const double &value) +{ + if (SQLITE_OK != ::sqlite3_bind_double(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } + +} + +void Statement::bind(const int index, const char *value) +{ + if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value, -1, SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const int index, const std::string &value) +{ + if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value.c_str(), + static_cast(value.size()), SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const int index, const void *value, const int size) +{ + if (SQLITE_OK != ::sqlite3_bind_blob(statement, index, value, size, SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const int index) +{ + if (SQLITE_OK != ::sqlite3_bind_null(statement, index)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const int &value) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != sqlite3_bind_int(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const sqlite3_int64 &value) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_int64(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const double &value) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_double(statement, index, value)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const std::string &value) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value.c_str(), + static_cast(value.size()), SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const char *value) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value, -1, SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name, const void *value, const int size) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_blob(statement, index, value, size, SQLITE_TRANSIENT)) { + throw std::runtime_error(getErrorMessage()); + } +} + +void Statement::bind(const std::string &name) +{ + int index = sqlite3_bind_parameter_index(statement, name.c_str()); + if (SQLITE_OK != ::sqlite3_bind_null(statement, index)) { + throw std::runtime_error(getErrorMessage()); + } +} + +} // namespace Database + +} // namespace Csr diff --git a/src/framework/database/statement.h b/src/framework/database/statement.h new file mode 100644 index 0000000..c49c537 --- /dev/null +++ b/src/framework/database/statement.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __STATEMENT__ +#define __STATEMENT__ + +#include +#include + +#include + +namespace Csr { + +namespace Database { + +class Column; +class Connection; + +class Statement { +public: + Statement(const Connection &db, const std::string &query); + virtual ~Statement(); + + int exec(); + bool step(); + + void reset(); + void clearBindings(); + std::string getErrorMessage() const; + std::string getErrorMessage(int errorCode) const; + + Column getColumn(const int index); + std::string getColumnName(const int index) const; + bool isNullColumn(const int index) const; + + void bind(const int index, const int &value); + void bind(const int index, const sqlite3_int64 &value); + void bind(const int index, const double &value); + void bind(const int index, const std::string &value); + void bind(const int index, const char *value); + void bind(const int index, const void *value, const int size); + void bind(const int index); + + void bind(const std::string &name, const int &value); + void bind(const std::string &name, const sqlite3_int64 &value); + void bind(const std::string &name, const double &value); + void bind(const std::string &name, const std::string &value); + void bind(const std::string &name, const char *value); + void bind(const std::string &name, const void *value, const int size); + void bind(const std::string &name); + + inline int getColumnCount() const { + return columnCount; + } + + inline sqlite3_stmt *get() const noexcept { + return statement; + } + +private: + typedef std::map ColumnMap; + + sqlite3_stmt *statement; + int columnCount; + int validRow; + ColumnMap columnNames; +}; + +} // namespace Database + +} // namespace Csr +#endif //__STATEMENT__ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bea5d44..aa1f420 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,22 +19,32 @@ FIND_PACKAGE(Threads REQUIRED) ADD_DEFINITIONS("-DBOOST_TEST_DYN_LINK") +SET(CSR_FW_SRC_PATH ${PROJECT_SOURCE_DIR}/src/framework) +SET(CSR_FW_DB_SRC_PATH ${CSR_FW_SRC_PATH}/database) + PKG_CHECK_MODULES(${TARGET_CSR_TEST}_DEP REQUIRED + sqlite3 ) SET(${TARGET_CSR_TEST}_SRCS + ${CSR_FW_DB_SRC_PATH}/column.cpp + ${CSR_FW_DB_SRC_PATH}/connection.cpp + ${CSR_FW_DB_SRC_PATH}/statement.cpp + ${CSR_FW_DB_SRC_PATH}/csr_db.cpp colour_log_formatter.cpp test-api-content-screening.cpp test-api-engine-manager.cpp test-api-web-protection.cpp test-api-engine-content-screening.cpp test-api-engine-web-protection.cpp + test-internal-database.cpp test-main.cpp ) INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/include + ${CSR_FW_SRC_PATH} ./ ${${TARGET_CSR_TEST}_DEP_INCLUDE_DIRS} ) diff --git a/test/test-internal-database.cpp b/test/test-internal-database.cpp new file mode 100644 index 0000000..6e7f8ef --- /dev/null +++ b/test/test-internal-database.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 + */ +/* + * @file test-internal-database.cpp + * @author Dongsun Lee(ds73.lee@samsung.com) + * @version 1.0 + * @brief CSR Content screening DB internal test + */ + +#include "database/csr_db.h" +#include +#include +#include + +#include + +#define TEST_DB_FILE TEST_DIR "/test.db" +#define TEST_DB_SCRIPTS RO_DBSPACE + +namespace { + +inline void checkSameMalware(Csr::Database::RowDetected &malware1, Csr::Database::RowDetected &malware2) +{ + BOOST_REQUIRE_MESSAGE(malware1.path.compare(malware2.path) == 0, + "Failed. checkSameMalware. path1=" << malware1.path << ", path2=" << malware2.path); + + BOOST_REQUIRE_MESSAGE(malware1.dataVersion.compare(malware2.dataVersion) == 0, + "Failed. checkSameMalware. dataVersion1=" << malware1.dataVersion + << ", dataVersion2=" << malware2.dataVersion); + + BOOST_REQUIRE_MESSAGE(malware1.severityLevel == malware2.severityLevel, + "Failed. checkSameMalware. severityLevel1=" << malware1.severityLevel + << ", severityLevel2=" << malware2.severityLevel); + + BOOST_REQUIRE_MESSAGE(malware1.threatType == malware2.threatType, + "Failed. checkSameMalware. threatType1=" << malware1.threatType + << ", threatType2=" << malware2.threatType); + + BOOST_REQUIRE_MESSAGE(malware1.name.compare(malware2.name) == 0, + "Failed. checkSameMalware. name1=" << malware1.name + << ", name2=" << malware2.name); + + BOOST_REQUIRE_MESSAGE(malware1.detailedUrl.compare(malware2.detailedUrl) == 0, + "Failed. checkSameMalware. detailedUrl1=" << malware1.detailedUrl + << ", detailedUrl2=" << malware2.detailedUrl); + + BOOST_REQUIRE_MESSAGE(malware1.detected_time == malware2.detected_time, + "Failed. checkSameMalware. detected_time1=" << malware1.detected_time + << ", detected_time2=" << malware2.detected_time); + + BOOST_REQUIRE_MESSAGE(malware1.modified_time == malware2.modified_time, + "Failed. checkSameMalware. modified_time1=" << malware1.modified_time + << ", modified_time2=" << malware2.modified_time); + + BOOST_REQUIRE_MESSAGE(malware1.ignored == malware2.ignored, + "Failed. checkSameMalware. ignored1=" << malware1.ignored + << ", ignored2=" << malware2.ignored); +} + +} // end of namespace + + +BOOST_AUTO_TEST_SUITE(INTERNAL_DATABASE) + +BOOST_AUTO_TEST_CASE(schema_info) +{ + bool result; + Csr::Database::CsrDB db(TEST_DB_FILE, TEST_DB_SCRIPTS); + + int version = 1; + result = db.setDbVersion(version); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. setDbVersion"); + + version = db.getDbVersion(); + BOOST_REQUIRE_MESSAGE(version == 1, "Failed. getDbVersion. expected=1, actual=" << version); +} + +BOOST_AUTO_TEST_CASE(scan_time) +{ + bool result; + Csr::Database::CsrDB db(TEST_DB_FILE, TEST_DB_SCRIPTS); + + std::string dir = "/opt"; + long scantime = 100; + long retrievedTime; + std::string dataVersion = "1.0.0"; + + result = db.cleanLastScanTime(); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. cleanLastScanTime"); + + retrievedTime = db.getLastScanTime(dir, dataVersion); + BOOST_REQUIRE_MESSAGE(retrievedTime == -1, "Failed. getLastScanTime." + "expected=-1, actual=" << retrievedTime); + + result = db.insertLastScanTime(dir, scantime, dataVersion); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertLastScanTime"); + + result = db.insertLastScanTime(std::string("/opt/data"), scantime + 100, dataVersion); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertLastScanTime"); + + result = db.insertLastScanTime(std::string("/opt/data/etc"), scantime + 200, dataVersion); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertLastScanTime"); + + retrievedTime = db.getLastScanTime(dir, dataVersion); + BOOST_REQUIRE_MESSAGE(retrievedTime == scantime, "Failed. getLastScanTime." + "expected=" << scantime << ", actual=" << retrievedTime); + + result = db.cleanLastScanTime(); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. cleanLastScanTime"); +} + +BOOST_AUTO_TEST_CASE(detected_malware_file) +{ + bool result; + Csr::Database::CsrDB db(TEST_DB_FILE, TEST_DB_SCRIPTS); + + std::string initDataVersion = "1.0.0"; + std::string changedDataVersion = "2.0.0"; + + // insert + Csr::Database::RowDetected malware1; + malware1.path = "/opt/testmalware1"; + malware1.dataVersion = initDataVersion; + malware1.severityLevel = 1; + malware1.threatType = 1; + malware1.name = "testmalware1"; + malware1.detailedUrl = "http://detailed.malware.com"; + malware1.detected_time = 100; + malware1.modified_time = 100; + malware1.ignored = 1; + + Csr::Database::RowDetected malware2; + malware2.path = "/opt/testmalware2"; + malware2.dataVersion = initDataVersion; + malware2.severityLevel = 2; + malware2.threatType = 2; + malware2.name = "testmalware2"; + malware2.detailedUrl = "http://detailed2.malware.com"; + malware2.detected_time = 210; + malware2.modified_time = 210; + malware2.ignored = 2; + + Csr::Database::RowDetected malware3; + malware3.path = "/opt/testmalware3"; + malware3.dataVersion = changedDataVersion; + malware3.severityLevel = 3; + malware3.threatType = 3; + malware3.name = "testmalware2"; + malware3.detailedUrl = "http://detailed2.malware.com"; + malware3.detected_time = 310; + malware3.modified_time = 310; + malware3.ignored = 3; + + // select test with vacant data + Csr::Database::DetectedShrPtr detected = db.getDetectedMalware(malware1.path); + BOOST_REQUIRE_MESSAGE(detected == nullptr, "Failed. getDetectedMalware for no data"); + + Csr::Database::DetectedListShrPtr detectedList = db.getDetectedMalwares(std::string("/opt")); + BOOST_REQUIRE_MESSAGE(detectedList->size() == 0, "Failed. getDetectedMalwares for no data. size=" + << detectedList->size()); + + // insertDetectedMalware test + result = db.insertDetectedMalware(malware1); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertDetectedMalware"); + + result = db.insertDetectedMalware(malware2); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertDetectedMalware"); + + // getDetectedMalware test + detected = db.getDetectedMalware(malware1.path); + checkSameMalware(malware1, *detected.get()); + + detected = db.getDetectedMalware(malware2.path); + checkSameMalware(malware2, *detected.get()); + + // getDetectedMalwares test + detectedList = db.getDetectedMalwares(std::string("/opt")); + BOOST_REQUIRE_MESSAGE(detectedList->size() == 2, "Failed. getDetectedMalwares. Size=" + << detectedList->size()); + std::vector::iterator iter; + for (iter = detectedList->begin(); iter != detectedList->end(); iter++) { + if (malware1.path.compare((*iter)->path) == 0) { + checkSameMalware(malware1, **iter); + } else if (malware2.path.compare((*iter)->path) == 0) { + checkSameMalware(malware2, **iter); + } else { + BOOST_REQUIRE_MESSAGE(false, "Failed. getDetectedMalwares"); + } + } + + // setDetectedMalwareIgnored test + result = db.setDetectedMalwareIgnored(malware1.path, 1); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. setDetectedMalwareIgnored"); + + malware1.ignored = 1; + detected = db.getDetectedMalware(malware1.path); + checkSameMalware(malware1, *detected.get()); + + // deleteDeprecatedDetecedMalwares test + result = db.insertDetectedMalware(malware3); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. insertDetectedMalware"); + + result = db.deleteDeprecatedDetecedMalwares(std::string("/opt"), changedDataVersion); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. deleteDeprecatedDetecedMalwares"); + + detected = db.getDetectedMalware(malware3.path); + checkSameMalware(malware3, *detected.get()); + + detected = db.getDetectedMalware(malware1.path); + BOOST_REQUIRE_MESSAGE(detected.get() == nullptr, + "Failed. deleteDeprecatedDetecedMalwares:getDetectedMalware"); + detected = db.getDetectedMalware(malware2.path); + BOOST_REQUIRE_MESSAGE(detected.get() == nullptr, + "Failed. deleteDeprecatedDetecedMalwares:getDetectedMalware"); + + // deleteDetecedMalware test + result = db.deleteDetecedMalware(malware3.path); + BOOST_REQUIRE_MESSAGE(result == true, "Failed. deleteDetecedMalware"); +} + + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4