M CMakeLists.txt => CMakeLists.txt +20 -1
@@ 28,6 28,7 @@ include(DiskImage)
include(AddPackage)
include(AutoModuleOption)
include(AddDirectories)
+include(AddDatabases)
message("Selected product: ${PRODUCT}")
message("Selected board: ${BOARD}")
@@ 168,12 169,30 @@ add_custom_target(
"Generating version info"
)
+# Create common user directories
add_directories(
TARGET user_directories_common
PREFIX ${CMAKE_BINARY_DIR}/sysroot/sys/user
DEPENDS assets
- DIRECTORIES logs crash_dumps backup tmp storage audio
+ DIRECTORIES logs crash_dumps backup tmp storage audio db
)
+
+# Create and initialize common databases
+add_databases_target(
+ TARGET create_databases_common
+ SOURCE_DIR ${CMAKE_SOURCE_DIR}/module-db/databases/scripts
+ DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/sys/user/db
+ DEVEL ${WITH_DEVELOPMENT_FEATURES}
+)
+# Create and initialize product-specific databases
+add_databases_target(
+ TARGET create_product_databases
+ SOURCE_DIR ${CMAKE_SOURCE_DIR}/products/${PRODUCT}/services/db/databases/scripts
+ DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/sys/user/db
+ DEVEL ${WITH_DEVELOPMENT_FEATURES}
+ DEPENDS create_databases_common
+)
+
add_library(version-header INTERFACE)
target_include_directories(version-header INTERFACE $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/source/include>)
add_dependencies(version-header version)
A cmake/modules/AddDatabases.cmake => cmake/modules/AddDatabases.cmake +32 -0
@@ 0,0 1,32 @@
+#[[
+Example of use:
+add_databases_target(
+ TARGET <target_name>
+ SOURCE_DIR <source_dir>
+ DEST_DIR <destination_dir>
+ DEVEL <true/false>
+ DEPENDS <dependencies list>
+)
+]]#
+function(add_databases_target)
+ cmake_parse_arguments(
+ _ARG
+ ""
+ "TARGET;SOURCE_DIR;DEST_DIR;DEVEL;"
+ "DEPENDS"
+ ${ARGN}
+ )
+
+ if (${_ARG_DEVEL} STREQUAL "ON")
+ set (DEVEL --development True)
+ endif()
+
+ add_custom_target(
+ ${_ARG_TARGET}
+ DEPENDS ${_ARG_DEPENDS}
+
+ COMMAND python3 ${PROJECT_SOURCE_DIR}/tools/init_databases.py --input_path ${_ARG_SOURCE_DIR} --output_path ${_ARG_DEST_DIR} ${DEVEL}
+ COMMENT
+ "Creating databases using schemas from: ${_ARG_SOURCE_DIR} and storing them under: ${_ARG_DEST_DIR}"
+ )
+endfunction()<
\ No newline at end of file
M cmake/modules/Assets.cmake => cmake/modules/Assets.cmake +1 -3
@@ 23,13 23,11 @@ function(add_assets_target)
${_ASSETS_DEST_DIR}
COMMAND rsync -qravu
${_ASSETS_SOURCE_DIR}/assets
- ${_ASSETS_SOURCE_DIR}/country-codes.db
${_ASSETS_DEST_DIR}/current
COMMAND rsync -qravu ${EXCLUDED}
${_ASSETS_SOURCE_DIR}/user
${_ASSETS_DEST_DIR}
- COMMAND find ${_ASSETS_DEST_DIR} -name "*-devel*" | sed "\"s,\\(.*\\)-devel\\(.*\\),& \\1\\2,\"" | xargs --no-run-if-empty -L1 mv
COMMENT
- "Copying assets.. add_assets_target (${_ASSETS_TARGET}) <- ${_ASSETS_DEPENDS}"
+ "Copying assets, development features: ${_ASSETS_DEVEL}"
)
endfunction()
M cmake/modules/ProjectConfig.cmake => cmake/modules/ProjectConfig.cmake +0 -3
@@ 87,6 87,3 @@ set(PROJECT_CONFIG_DEFINITIONS
PROF_ON=${PROF_ON}
CACHE INTERNAL ""
)
-
-message(STATUS "BlueKitchen selected")
-set(BT_STACK "BlueKitchen")
M config/apply_update.sh => config/apply_update.sh +0 -1
@@ 99,7 99,6 @@ fi
echo "Copyind data"
cp $TMPDIR/boot.bin $PHONE_MOUNT/current/
cp $TMPDIR/Luts.bin $PHONE_MOUNT/current/
-cp $TMPDIR/country-codes.db $PHONE_MOUNT/current/
cp $TMPDIR/version.json $PHONE_MOUNT/current/
cp -r $TMPDIR/assets $PHONE_MOUNT/current/
D image/user/db/settings_001.sql => image/user/db/settings_001.sql +0 -11
@@ 1,11 0,0 @@
--- Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
--- For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-INSERT OR REPLACE INTO settings_tab (path, value) VALUES
- ('timeFormat', '0'),
- ('dateFormat', '1'),
- ('activeSim', '1'),
- ('lockPassHash', '0'),
- ('lockTime', '30000'),
- ('displayLanguage', 'En'),
- ('inputLanguag', 'En');
M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +0 -15
@@ 143,18 143,3 @@ target_compile_options(apps-common
$<$<COMPILE_LANGUAGE:CXX>:-Wno-literal-suffix>
)
-
-# Bell Hybrid related libs
-add_library(bellgui)
-target_sources( bellgui
- PRIVATE
-)
-target_include_directories( bellgui
- PUBLIC
- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/options/type>
-)
-
-target_link_libraries( bellgui
- PRIVATE
- module-gui
-)
M module-cellular/at/src/UrcQind.cpp => module-cellular/at/src/UrcQind.cpp +1 -1
@@ 40,7 40,7 @@ auto Qind::getFotaStage() const noexcept -> std::optional<FotaStage>
auto Qind::getFotaParameter() const noexcept -> std::string
{
- if (isFotaValid() && tokens.size() >= fotaMinTokenSize) {
+ if (isFotaValid() && tokens.size() > fotaMinTokenSize) {
return tokens[Param];
}
return std::string();
M module-db/CMakeLists.txt => module-db/CMakeLists.txt +9 -11
@@ 13,18 13,17 @@ set(SOURCES
Database/Field.cpp
Database/QueryResult.cpp
Database/Database.cpp
- Database/DatabaseInitializer.cpp
Database/sqlite3vfs.cpp
${SQLITE3_SOURCE}
- Databases/CalllogDB.cpp
- Databases/ContactsDB.cpp
- Databases/CountryCodesDB.cpp
- Databases/EventsDB.cpp
- Databases/MultimediaFilesDB.cpp
- Databases/NotesDB.cpp
- Databases/NotificationsDB.cpp
- Databases/SmsDB.cpp
+ databases/EventsDB.cpp
+ databases/MultimediaFilesDB.cpp
+
+ databases/CalllogDB.cpp
+ databases/ContactsDB.cpp
+ databases/NotesDB.cpp
+ databases/NotificationsDB.cpp
+ databases/SmsDB.cpp
Tables/AlarmEventsTable.cpp
Tables/Table.cpp
@@ 38,7 37,6 @@ set(SOURCES
Tables/ContactsGroups.cpp
Tables/NotesTable.cpp
Tables/CalllogTable.cpp
- Tables/CountryCodesTable.cpp
Tables/SMSTemplateTable.cpp
Tables/NotificationsTable.cpp
Tables/MultimediaFilesTable.cpp
@@ 153,7 151,7 @@ target_include_directories(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Interface
${CMAKE_CURRENT_SOURCE_DIR}/Tables
- ${CMAKE_CURRENT_SOURCE_DIR}/Databases
+ ${CMAKE_CURRENT_SOURCE_DIR}/databases
${CMAKE_CURRENT_SOURCE_DIR}/Database
)
A module-db/Common/Types.hpp => module-db/Common/Types.hpp +13 -0
@@ 0,0 1,13 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+/// 32-bit unsigned integer
+#define u32_ "%" PRIu32
+/// 32-bit unsigned integer with comma, for instance: 323,
+#define u32_c "%" PRIu32 ","
+/// Zero terminated string with single-quotes on both ends, for instance: 'my string'
+#define str_ "%Q"
+/// The same as above with additional comma at the end, for instance: 'my string',
+#define str_c "%Q,"<
\ No newline at end of file
M module-db/Database/Database.cpp => module-db/Database/Database.cpp +4 -30
@@ 2,16 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "Database.hpp"
-#include "DatabaseInitializer.hpp"
#include <log/log.hpp>
-
-#include <purefs/filesystem_paths.hpp>
#include <gsl/util>
-
-#include <cassert>
#include <cstring>
-#include <memory>
/* Declarations *********************/
extern sqlite3_vfs *sqlite3_ecophonevfs(void);
@@ 75,8 69,7 @@ constexpr auto dbApplicationId = 0x65727550; // ASCII for "Pure"
constexpr auto enabled = 1;
Database::Database(const char *name, bool readOnly)
- : dbConnection(nullptr), dbName(name), queryStatementBuffer{nullptr}, isInitialized_(false),
- initializer(std::make_unique<DatabaseInitializer>(this))
+ : dbConnection(nullptr), dbName(name), queryStatementBuffer{nullptr}, isInitialized_(false)
{
const int flags = (readOnly) ? (SQLITE_OPEN_READONLY) : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
LOG_INFO("Opening database: %s", dbName.c_str());
@@ 89,30 82,11 @@ Database::Database(const char *name, bool readOnly)
pragmaQuery("PRAGMA integrity_check;");
pragmaQuery("PRAGMA locking_mode=EXCLUSIVE");
- if (pragmaQueryForValue("PRAGMA application_id;", dbApplicationId)) {
- LOG_DEBUG("Database %s initialized", dbName.c_str());
- isInitialized_ = true;
- return;
- }
-
- /** Workaround for [MOS-351].
- * Updater app loads databases to wrong directory (1/current/user/db) rather than
- * (3/user/db). Therefore, we need to check both directories to support both flashing image and updating through
- * updater.
- * !!! This workaround should be removed with minor patch of updater, however it cannot be released in one package
- * with database changes.
- **/
- auto filePath = (purefs::dir::getCurrentOSPath() / "user/db");
- if (!std::filesystem::exists(filePath)) {
- filePath = (purefs::dir::getUserDiskPath() / "db");
- }
-
- LOG_INFO("Running scripts: %s", filePath.c_str());
- isInitialized_ = initializer->run(filePath.c_str(), InitScriptExtension);
-
- if (isInitialized_) {
+ if (isInitialized_ = pragmaQueryForValue("PRAGMA application_id;", dbApplicationId); not isInitialized_) {
populateDbAppId();
+ isInitialized_ = true;
}
+ LOG_DEBUG("Database %s initialized", dbName.c_str());
}
void Database::populateDbAppId()
M module-db/Database/Database.hpp => module-db/Database/Database.hpp +1 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 10,8 10,6 @@
#include <stdexcept>
#include <filesystem>
-class DatabaseInitializer;
-
class DatabaseInitialisationError : public std::runtime_error
{
public:
@@ 52,7 50,6 @@ class Database
}
private:
- static constexpr auto InitScriptExtension = "sql";
static constexpr std::uint32_t maxQueryLen = (8 * 1024);
void initQueryStatementBuffer();
@@ 75,5 72,4 @@ class Database
std::string dbName;
char *queryStatementBuffer;
bool isInitialized_;
- std::unique_ptr<DatabaseInitializer> initializer;
};
D module-db/Database/DatabaseInitializer.cpp => module-db/Database/DatabaseInitializer.cpp +0 -142
@@ 1,142 0,0 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "DatabaseInitializer.hpp"
-
-#include <log/log.hpp>
-#include <Utils.hpp>
-
-#include <algorithm>
-#include <cstdio>
-#include <memory>
-#include <array>
-#include <set>
-#include <string>
-#include <sstream>
-#include <array>
-
-DatabaseInitializer::DatabaseInitializer(Database *db) : db(db)
-{}
-
-bool DatabaseInitializer::run(std::filesystem::path path, std::string ext)
-{
- // Database name is database file path, need to strip off all filesystem related stuff(path, extension)
- std::filesystem::path dbpath = db->getName();
- std::string dbname = dbpath.filename().replace_extension();
-
- for (int i = 1;; i++) {
- auto fname = std::make_unique<std::stringstream>();
- (*fname) << dbname << "_" << std::setfill('0') << std::setw(3) << i << '.' << ext;
- auto file = path / fname->str();
- LOG_DEBUG("Running db script: %s", file.c_str());
- auto commands = readCommands(file);
- if (commands.empty())
- break;
- if (!executeOnDb(commands)) {
- LOG_ERROR("Can't initialize database [%s] with [%s]", db->getName().c_str(), file.c_str());
- return false;
- }
- }
- return true;
-}
-
-std::string DatabaseInitializer::readContent(const char *filename) const noexcept
-{
- std::unique_ptr<char[]> fcontent;
- long fsize = 0;
-
- auto fp = std::fopen(filename, "r");
- if (fp) {
- std::fseek(fp, 0, SEEK_END);
- fsize = std::ftell(fp);
- std::rewind(fp);
-
- fcontent = std::make_unique<char[]>(fsize + 1);
-
- std::fread(fcontent.get(), 1, fsize, fp);
-
- std::fclose(fp);
- }
- else
- return {};
-
- return std::string(fcontent.get());
-}
-
-std::vector<std::string> DatabaseInitializer::readCommands(std::filesystem::path filePath)
-{
- auto fileContent = readContent(filePath.c_str());
- if (fileContent.empty())
- return {};
-
- std::string currentStatement{};
- std::vector<std::string> statements{};
-
- std::string line{};
- for (auto &c : fileContent) {
- if (c != '\n') {
- line += c;
- }
- else {
- if (line.empty() || utils::startsWith(line, "--")) {
- line.clear();
- continue;
- }
- if (utils::endsWith(line, ";")) {
- statements.push_back(currentStatement + line);
- currentStatement.clear();
- line.clear();
- continue;
- }
- currentStatement += line;
-
- line.clear();
- }
- }
- return statements;
-}
-
-std::array<std::string, 3> DatabaseInitializer::splitFilename(std::string filename)
-{
- auto name = filename.substr(0, filename.find("."));
- auto prefix = name.substr(0, name.find_last_of("_"));
- auto postfix = name.substr(name.find_last_of("_") + 1, std::string::npos);
-
- return {name, prefix, postfix};
-}
-
-std::vector<std::filesystem::path> DatabaseInitializer::listFiles(std::filesystem::path path,
- std::string prefix,
- std::string ext)
-{
- std::set<std::pair<int, std::filesystem::path>> orderedFiles;
- for (const auto &entry : std::filesystem::directory_iterator(path)) {
- if (!entry.is_directory() && entry.path().has_filename()) {
- try {
- auto parts = splitFilename(entry.path().filename().string());
- auto filePrefix = parts[1];
- if (filePrefix == prefix) {
- auto num = std::stoi(parts[2]);
- orderedFiles.insert({num, entry.path()});
- }
- }
- catch (std::invalid_argument &e) {
- LOG_INFO("Ignoring file: %s", entry.path().c_str());
- }
- }
- }
-
- std::vector<std::filesystem::path> files;
- std::for_each(orderedFiles.begin(), orderedFiles.end(), [&](auto item) { files.push_back(item.second); });
- return files;
-}
-
-bool DatabaseInitializer::executeOnDb(const std::vector<std::string> statements)
-{
- for (auto st : statements) {
- if (!db->execute(st.c_str())) {
- return false;
- }
- }
- return true;
-}
D module-db/Database/DatabaseInitializer.hpp => module-db/Database/DatabaseInitializer.hpp +0 -58
@@ 1,58 0,0 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include "Database.hpp"
-#include <fstream>
-#include <filesystem>
-
-class DatabaseInitializer
-{
- class ScopedFile
- {
- public:
- ScopedFile(std::string path, std::string mode)
- {
- file = std::fopen(path.c_str(), mode.c_str());
- }
-
- ~ScopedFile()
- {
- std::fclose(file);
- }
-
- [[nodiscard]] std::FILE *get() const
- {
- return file;
- }
-
- private:
- std::FILE *file = nullptr;
- };
-
- public:
- DatabaseInitializer(Database *db);
- ~DatabaseInitializer() = default;
-
- auto run(std::filesystem::path path, std::string ext = "sql") -> bool;
-
- auto readCommands(std::filesystem::path filePath) -> std::vector<std::string>;
-
- auto listFiles(std::filesystem::path path, std::string prefix, std::string ext)
- -> std::vector<std::filesystem::path>;
-
- auto executeOnDb(const std::vector<std::string> statements) -> bool;
-
- private:
- /*
- * Splits filename in format <prefix>_<num>.ext into array
- * [0] - filename
- * [1] - prefix
- * [2] - num
- */
- auto splitFilename(std::string filename) -> std::array<std::string, 3>;
- std::string readContent(const char *filename) const noexcept;
-
- Database *db = nullptr;
-};
D module-db/Databases/CountryCodesDB.cpp => module-db/Databases/CountryCodesDB.cpp +0 -14
@@ 1,14 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "CountryCodesDB.hpp"
-
-CountryCodesDB::CountryCodesDB(const char *name) : Database(name, true), countryCodes(this)
-{
- if (countryCodes.create() == false)
- return;
- isInitialized_ = true;
-}
-
-CountryCodesDB::~CountryCodesDB()
-{}
D module-db/Databases/CountryCodesDB.hpp => module-db/Databases/CountryCodesDB.hpp +0 -15
@@ 1,15 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-#include "Database/Database.hpp"
-#include "Tables/CountryCodesTable.hpp"
-
-class CountryCodesDB : public Database
-{
- public:
- CountryCodesDB(const char *name);
- ~CountryCodesDB();
-
- CountryCodesTable countryCodes;
-};
M module-db/Interface/AlarmEventRecord.cpp => module-db/Interface/AlarmEventRecord.cpp +1 -1
@@ 3,7 3,7 @@
#include "AlarmEventRecord.hpp"
-#include <Databases/EventsDB.hpp>
+#include <databases/EventsDB.hpp>
#include <queries/alarm_events/QueryAlarmEventsAdd.hpp>
#include <queries/alarm_events/QueryAlarmEventsEdit.hpp>
#include <queries/alarm_events/QueryAlarmEventsGet.hpp>
M module-db/Interface/AlarmEventRecord.hpp => module-db/Interface/AlarmEventRecord.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once
#include "EventRecord.hpp"
-#include <Databases/EventsDB.hpp>
+#include <databases/EventsDB.hpp>
#include <cstdint>
M module-db/Interface/BaseInterface.hpp => module-db/Interface/BaseInterface.hpp +0 -3
@@ 25,7 25,6 @@ namespace db
Contact,
Notes,
Calllog,
- CountryCodes,
Notifications,
Quotes,
MultimediaFiles
@@ 50,8 49,6 @@ constexpr const char *c_str(enum db::Interface::Name db)
return "Notes";
case db::Interface::Name::Calllog:
return "Callog";
- case db::Interface::Name::CountryCodes:
- return "CountryCodes";
case db::Interface::Name::Notifications:
return "Notifications";
case db::Interface::Name::Quotes:
M module-db/Interface/CalllogRecord.hpp => module-db/Interface/CalllogRecord.hpp +1 -1
@@ 5,7 5,7 @@
#include "Common/Common.hpp"
#include "ContactRecord.hpp"
-#include "Databases/CalllogDB.hpp"
+#include "module-db/databases/CalllogDB.hpp"
#include "Record.hpp"
#include "queries/calllog/QueryCalllogSetAllRead.hpp"
#include <PhoneNumber.hpp>
M module-db/Interface/ContactRecord.cpp => module-db/Interface/ContactRecord.cpp +1 -1
@@ 1214,7 1214,7 @@ auto ContactRecordInterface::addTemporaryContactForNumber(const ContactRecord::N
{
ContactRecord tmp;
tmp.numbers = std::vector<ContactRecord::Number>{number};
- tmp.addToGroup(ContactsDB::temporaryGroupId());
+ tmp.addToGroup(contactDB->groups.temporaryId());
if (!Add(tmp)) {
error_db_data("Cannot add contact record");
return std::nullopt;
M module-db/Interface/ContactRecord.hpp => module-db/Interface/ContactRecord.hpp +1 -1
@@ 5,7 5,7 @@
#include <Common/Query.hpp>
#include <Common/Logging.hpp>
-#include <Databases/ContactsDB.hpp>
+#include "module-db/databases/ContactsDB.hpp"
#include <Tables/ContactsGroups.hpp>
#include <i18n/i18n.hpp>
D module-db/Interface/CountryCodeRecord.hpp => module-db/Interface/CountryCodeRecord.hpp +0 -51
@@ 1,51 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include "../Common/Common.hpp"
-#include "../Databases/CountryCodesDB.hpp"
-#include "Record.hpp"
-#include "utf8/UTF8.hpp"
-
-#include <vector>
-
-struct CountryCodeRecord
-{
- uint32_t id;
- uint32_t mcc;
- uint32_t mnc;
- UTF8 iso;
- UTF8 country;
- uint32_t country_code;
- UTF8 network;
-};
-
-enum class CountryCodeRecordField
-{
- MCC,
- MNC,
- ISO,
- Country
-};
-
-class CountryCodeRecordInterface : public RecordInterface<CountryCodeRecord, CountryCodeRecordField>
-{
-
- public:
- CountryCodeRecordInterface(CountryCodesDB *db) : codesDB(db)
- {}
- ~CountryCodeRecordInterface()
- {}
- CodesTableRow GetByMCC(uint32_t mcc)
- {
- if (codesDB) {
- return (codesDB->countryCodes.GetByMCC(mcc));
- }
-
- return (CodesTableRow());
- }
-
- private:
- CountryCodesDB *codesDB;
-};
M module-db/Interface/MultimediaFilesRecord.cpp => module-db/Interface/MultimediaFilesRecord.cpp +1 -1
@@ 4,7 4,7 @@
#include "MultimediaFilesRecord.hpp"
#include "BaseInterface.hpp"
-#include <Databases/MultimediaFilesDB.hpp>
+#include <databases/MultimediaFilesDB.hpp>
#include <queries/multimedia_files/QueryMultimediaFilesAdd.hpp>
#include <queries/multimedia_files/QueryMultimediaFilesEdit.hpp>
#include <queries/multimedia_files/QueryMultimediaFilesGet.hpp>
M module-db/Interface/NotesRecord.hpp => module-db/Interface/NotesRecord.hpp +1 -1
@@ 10,7 10,7 @@
#include <utf8/UTF8.hpp>
-#include "module-db/Databases/NotesDB.hpp"
+#include "module-db/databases/NotesDB.hpp"
#include "../Common/Common.hpp"
struct NotesRecord : public Record
M module-db/Interface/NotificationsRecord.cpp => module-db/Interface/NotificationsRecord.cpp +1 -1
@@ 8,7 8,7 @@
#include "module-db/queries/notifications/QueryNotificationsMultipleIncrement.hpp"
#include "module-db/queries/notifications/QueryNotificationsClear.hpp"
#include "module-db/queries/notifications/QueryNotificationsGetAll.hpp"
-#include "Databases/NotificationsDB.hpp"
+#include "module-db/databases/NotificationsDB.hpp"
#include <log/log.hpp>
#include <Utils.hpp>
M module-db/Interface/SMSRecord.hpp => module-db/Interface/SMSRecord.hpp +2 -2
@@ 7,8 7,8 @@
#include "Record.hpp"
#include "ThreadRecord.hpp"
-#include "module-db/Databases/SmsDB.hpp"
-#include "module-db/Databases/ContactsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include "module-db/Common/Common.hpp"
#include <utf8/UTF8.hpp>
M module-db/Interface/SMSTemplateRecord.hpp => module-db/Interface/SMSTemplateRecord.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once
#include "Record.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include "Common/Common.hpp"
#include <utf8/UTF8.hpp>
M module-db/Interface/SettingsRecord.hpp => module-db/Interface/SettingsRecord.hpp +1 -1
@@ 6,7 6,7 @@
#include "Record.hpp"
#include "utf8/UTF8.hpp"
#include "../Common/Common.hpp"
-#include "../Databases/SettingsDB.hpp"
+#include "../databases/SettingsDB.hpp"
#include <i18n/i18n.hpp>
struct SettingsRecord
M module-db/Interface/ThreadRecord.hpp => module-db/Interface/ThreadRecord.hpp +2 -2
@@ 4,8 4,8 @@
#pragma once
#include "Record.hpp"
-#include "module-db/Databases/SmsDB.hpp"
-#include "module-db/Databases/ContactsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include "module-db/Common/Common.hpp"
#include "module-db/queries/messages/threads/QueryThreadMarkAsRead.hpp"
#include <PhoneNumber.hpp>
M module-db/Tables/AlarmEventsTable.cpp => module-db/Tables/AlarmEventsTable.cpp +17 -31
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "AlarmEventsTable.hpp"
+#include "Common/Types.hpp"
#include <Interface/AlarmEventRecord.hpp>
@@ 50,7 51,7 @@ bool AlarmEventsTable::create()
bool AlarmEventsTable::add(AlarmEventsTableRow entry)
{
return db->execute("INSERT or ignore INTO alarms ( hour, minute, music_tone, enabled, snooze_duration, rrule)"
- "VALUES ( %lu, %lu, '%q', %d, %lu, '%q');",
+ "VALUES (" u32_c u32_c str_c u32_c u32_c str_ ");",
entry.hourOfDay,
entry.minuteOfHour,
entry.musicTone.c_str(),
@@ 61,16 62,13 @@ bool AlarmEventsTable::add(AlarmEventsTableRow entry)
bool AlarmEventsTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM alarms "
- "WHERE alarms._id = %lu;",
- id);
+ return db->execute("DELETE FROM alarms WHERE alarms._id=" u32_ ";", id);
}
bool AlarmEventsTable::update(AlarmEventsTableRow entry)
{
- return db->execute("UPDATE alarms SET hour = '%lu', minute = '%lu', music_tone = '%q', enabled = '%d', "
- "snooze_duration = '%lu', rrule = '%q' "
- "WHERE _id=%lu;",
+ return db->execute("UPDATE alarms SET hour=" u32_c "minute=" u32_c "music_tone=" str_c "enabled=" u32_c
+ "snooze_duration=" u32_c "rrule=" str_ " WHERE _id=" u32_ ";",
entry.hourOfDay,
entry.minuteOfHour,
entry.musicTone.c_str(),
@@ 82,10 80,7 @@ bool AlarmEventsTable::update(AlarmEventsTableRow entry)
AlarmEventsTableRow AlarmEventsTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * "
- "FROM alarms "
- "WHERE _id = %lu;",
- id);
+ auto retQuery = db->query("SELECT * FROM alarms WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return AlarmEventsTableRow();
@@ 96,19 91,15 @@ AlarmEventsTableRow AlarmEventsTable::getById(uint32_t id)
std::vector<AlarmEventsTableRow> AlarmEventsTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * FROM alarms "
- "ORDER BY hour, minute "
- "LIMIT %lu OFFSET %lu;",
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * FROM alarms ORDER BY hour, minute LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
return retQueryUnpack(std::move(retQuery));
}
std::vector<AlarmEventsTableRow> AlarmEventsTable::getEnabled()
{
- auto retQuery = db->query("SELECT * FROM alarms "
- "WHERE enabled = 1;");
+ auto retQuery = db->query("SELECT * FROM alarms WHERE enabled = 1;");
return retQueryUnpack(std::move(retQuery));
}
@@ 125,21 116,19 @@ std::vector<AlarmEventsTableRow> AlarmEventsTable::getLimitOffsetByField(uint32_
return {};
}
- retQuery = db->query("SELECT * FROM alarms e "
- "WHERE %q = '%q' "
- "ORDER BY hour, minute "
- "LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ retQuery =
+ db->query("SELECT * FROM alarms e WHERE %q=" str_ "ORDER BY hour, minute LIMIT " u32_ " OFFSET " u32_c ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
return retQueryUnpack(std::move(retQuery));
}
auto AlarmEventsTable::toggleAll(bool toggle) -> bool
{
- auto ret = db->execute("UPDATE alarms SET enabled = '%d';", static_cast<int>(toggle));
+ auto ret = db->execute("UPDATE alarms SET enabled=" u32_ ";", static_cast<int>(toggle));
return ret;
}
@@ 156,10 145,7 @@ uint32_t AlarmEventsTable::count()
uint32_t AlarmEventsTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM alarms "
- "WHERE %q=%lu;",
- field,
- id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM alarms WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
}
M module-db/Tables/CalllogTable.cpp => module-db/Tables/CalllogTable.cpp +25 -23
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CalllogTable.hpp"
+#include "Common/Types.hpp"
#include <log/log.hpp>
#include <Utils.hpp>
@@ 18,23 19,22 @@ bool CalllogTable::create()
bool CalllogTable::add(CalllogTableRow entry)
{
- return db->execute(
- "INSERT or ignore INTO calls (number, e164number, presentation, date, duration, type, name, contactId, "
- "isRead) VALUES ('%q', '%q', %lu, %q, %q, %lu, '%q', '%lu', %d);",
- entry.number.c_str(),
- entry.e164number.c_str(),
- static_cast<uint32_t>(entry.presentation),
- utils::to_string(entry.date).c_str(),
- utils::to_string(entry.duration).c_str(),
- static_cast<uint32_t>(entry.type),
- entry.name.c_str(),
- entry.contactId,
- entry.isRead);
+ return db->execute("INSERT or ignore INTO calls (number, e164number, presentation, date, duration, type, name, "
+ "contactId,isRead) VALUES (" str_c str_c u32_c str_c str_c u32_c str_c u32_c u32_ ");",
+ entry.number.c_str(),
+ entry.e164number.c_str(),
+ static_cast<uint32_t>(entry.presentation),
+ utils::to_string(entry.date).c_str(),
+ utils::to_string(entry.duration).c_str(),
+ static_cast<uint32_t>(entry.type),
+ entry.name.c_str(),
+ entry.contactId,
+ entry.isRead);
}
bool CalllogTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM calls where _id = %lu;", id);
+ return db->execute("DELETE FROM calls where _id=" u32_ ";", id);
}
bool CalllogTable::removeByField(CalllogTableFields field, const char *str)
@@ 44,10 44,9 @@ bool CalllogTable::removeByField(CalllogTableFields field, const char *str)
bool CalllogTable::update(CalllogTableRow entry)
{
- return db->execute("UPDATE calls SET number = '%q', e164number = '%q', presentation = %lu, date = %lu, duration = "
- "%lu, type = %lu, "
- "name = '%q', contactId = '%u', isRead = "
- "%d WHERE _id = %lu;",
+ return db->execute("UPDATE calls SET number=" str_c "e164number=" str_c "presentation=" u32_c "date=" u32_c
+ "duration=" u32_c "type=" u32_c "name=" str_c "contactId=" u32_c "isRead=" u32_
+ " WHERE _id=" u32_ ";",
entry.number.c_str(),
entry.e164number.c_str(),
static_cast<uint32_t>(entry.presentation),
@@ 62,7 61,7 @@ bool CalllogTable::update(CalllogTableRow entry)
CalllogTableRow CalllogTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM calls WHERE _id= %u;", id);
+ auto retQuery = db->query("SELECT * FROM calls WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return CalllogTableRow();
@@ 84,7 83,7 @@ CalllogTableRow CalllogTable::getById(uint32_t id)
std::vector<CalllogTableRow> CalllogTable::getByContactId(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM calls WHERE contactId= %lu;", id);
+ auto retQuery = db->query("SELECT * FROM calls WHERE contactId=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<CalllogTableRow>();
@@ 112,7 111,7 @@ std::vector<CalllogTableRow> CalllogTable::getByContactId(uint32_t id)
std::vector<CalllogTableRow> CalllogTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from calls ORDER BY date DESC LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query("SELECT * from calls ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<CalllogTableRow>();
@@ 156,8 155,11 @@ std::vector<CalllogTableRow> CalllogTable::getLimitOffsetByField(uint32_t offset
return std::vector<CalllogTableRow>();
}
- auto retQuery = db->query(
- "SELECT * from calls WHERE %q='%q' ORDER BY date LIMIT %lu OFFSET %lu;", fieldName.c_str(), str, limit, offset);
+ auto retQuery = db->query("SELECT * from calls WHERE %q=" u32_ " ORDER BY date LIMIT " u32_ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<CalllogTableRow>();
@@ 213,7 215,7 @@ uint32_t CalllogTable::count()
uint32_t CalllogTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM calls WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM calls WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
M module-db/Tables/ContactsAddressTable.cpp => module-db/Tables/ContactsAddressTable.cpp +15 -12
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsAddressTable.hpp"
+#include "Common/Types.hpp"
ContactsAddressTable::ContactsAddressTable(Database *db) : Table(db)
{}
@@ 17,7 18,7 @@ bool ContactsAddressTable::create()
bool ContactsAddressTable::add(ContactsAddressTableRow entry)
{
return db->execute("insert or ignore into contact_address (contact_id, address, note, mail) "
- "VALUES (%lu, '%q', '%q', '%q');",
+ "VALUES (" u32_c str_c str_c str_ ");",
entry.contactID,
entry.address.c_str(),
entry.note.c_str(),
@@ 26,13 27,13 @@ bool ContactsAddressTable::add(ContactsAddressTableRow entry)
bool ContactsAddressTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM contact_address where _id = %u;", id);
+ return db->execute("DELETE FROM contact_address where _id=" u32_ ";", id);
}
bool ContactsAddressTable::update(ContactsAddressTableRow entry)
{
- return db->execute("UPDATE contact_address SET contact_id = %lu, address = '%q', note = '%q', mail = '%q' "
- "WHERE _id=%lu;",
+ return db->execute("UPDATE contact_address SET contact_id=" u32_c "address=" str_c "note=" str_c "mail=" str_
+ "WHERE _id=" u32_ ";",
entry.contactID,
entry.address.c_str(),
entry.note.c_str(),
@@ 42,7 43,7 @@ bool ContactsAddressTable::update(ContactsAddressTableRow entry)
ContactsAddressTableRow ContactsAddressTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM contact_address WHERE _id= %lu;", id);
+ auto retQuery = db->query("SELECT * FROM contact_address WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return ContactsAddressTableRow();
@@ 59,7 60,8 @@ ContactsAddressTableRow ContactsAddressTable::getById(uint32_t id)
std::vector<ContactsAddressTableRow> ContactsAddressTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from contact_address ORDER BY contact_id LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery =
+ db->query("SELECT * from contact_address ORDER BY contact_id LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsAddressTableRow>();
@@ 95,11 97,12 @@ std::vector<ContactsAddressTableRow> ContactsAddressTable::getLimitOffsetByField
return std::vector<ContactsAddressTableRow>();
}
- auto retQuery = db->query("SELECT * from contact_address WHERE %q='%q' ORDER BY contact_id LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * from contact_address WHERE %q=" str_ " ORDER BY contact_id LIMIT " u32_ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsAddressTableRow>();
@@ 133,7 136,7 @@ uint32_t ContactsAddressTable::count()
uint32_t ContactsAddressTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM contact_address WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM contact_address WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
M module-db/Tables/ContactsGroups.cpp => module-db/Tables/ContactsGroups.cpp +15 -18
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsGroups.hpp"
+#include "Common/Types.hpp"
namespace statements
{
@@ 12,8 13,8 @@ namespace statements
const char *blockedId = "SELECT _id FROM contact_groups WHERE name = 'Blocked';";
const char *temporaryId = "SELECT _id FROM contact_groups WHERE name = 'Temporary';";
- const char *getId = "SELECT _id FROM contact_groups WHERE name = '%q';";
- const char *getById = "SELECT _id, name FROM contact_groups WHERE _id = %u;";
+ const char *getId = "SELECT _id FROM contact_groups WHERE name=" str_ ";";
+ const char *getById = "SELECT _id, name FROM contact_groups WHERE _id=" u32_ ";";
/**
* delete a group only if it is not a "special group"
@@ 22,24 23,21 @@ namespace statements
* delete cg from contact_groups cg left join contact_group_protected cgp on cg._id=cgp.group_id where cgp._id is
* null; so we have the following statement
*/
- const char *deleteById = "DELETE FROM contact_groups WHERE _id = %u "
- "AND NOT EXISTS (SELECT * FROM contact_group_protected WHERE group_id=contact_groups._id)";
+ const char *deleteById =
+ "DELETE FROM contact_groups WHERE _id=" u32_
+ " AND NOT EXISTS (SELECT * FROM contact_group_protected WHERE group_id=contact_groups._id)";
- const char *getAllLimtOfset = "SELECT _id, name FROM contact_groups ORDER BY _id LIMIT %lu OFFSET %lu;";
+ const char *getAllLimtOfset = "SELECT _id, name FROM contact_groups ORDER BY _id LIMIT " u32_ " OFFSET " u32_ ";";
- const char *addGrup = "INSERT INTO contact_groups (name) VALUES ('%q');";
- const char *addProtectedGroup = "INSERT INTO conctact_group_protected (group_id) VALUES ('%u');";
- const char *updateGroupName = "UPDATE contact_groups SET name = '%q' WHERE _id = '%u';";
- const char *deleteGroup = "DELETE FROM table_name WHERE _id = :id;";
+ const char *addGrup = "INSERT INTO contact_groups (name) VALUES(" str_ ");";
+ const char *updateGroupName = "UPDATE contact_groups SET name=" str_ " WHERE _id=" u32_ ";";
- const char *addContactToGroup = "INSERT INTO contact_match_groups (contact_id, group_id)"
- " VALUES(%u, %u)";
+ const char *addContactToGroup = "INSERT INTO contact_match_groups (contact_id, group_id) VALUES(" u32_c u32_ ");";
const char *delContactFromGroup = "DELETE FROM contact_match_groups "
" WHERE "
- " contact_id = %u "
- " AND "
- " group_id = %u;";
+ " contact_id=" u32_ " AND "
+ " group_id=" u32_ ";";
const char *getGroupsForContact = "SELECT groups._id, groups.name "
" FROM contact_groups as groups,"
@@ 47,11 45,10 @@ namespace statements
" contacts "
" WHERE contacts._id = cmg.contact_id "
" AND groups._id = cmg.group_id "
- " AND contacts._id = %u "
- " ORDER BY groups._id ASC;";
+ " AND contacts._id=" u32_ " ORDER BY groups._id ASC;";
- const char *getContactsForGroup = "SELECT cmg.contact_id FROM contact_match_groups as cmg "
- " WHERE cmg.group_id = %u;";
+ const char *getContactsForGroup =
+ "SELECT cmg.contact_id FROM contact_match_groups as cmg WHERE cmg.group_id=" u32_ ";";
} // namespace statements
ContactsGroupsTable::ContactsGroupsTable(Database *db) : Table(db)
M module-db/Tables/ContactsNameTable.cpp => module-db/Tables/ContactsNameTable.cpp +20 -18
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsNameTable.hpp"
+#include "Common/Types.hpp"
#include <Utils.hpp>
ContactsNameTable::ContactsNameTable(Database *db) : Table(db)
@@ 18,7 19,7 @@ bool ContactsNameTable::create()
bool ContactsNameTable::add(ContactsNameTableRow entry)
{
return db->execute("insert or ignore into contact_name (contact_id, name_primary, name_alternative) "
- "VALUES (%lu, '%q', '%q');",
+ "VALUES (" u32_c str_c str_ ");",
entry.contactID,
entry.namePrimary.c_str(),
entry.nameAlternative.c_str());
@@ 26,13 27,13 @@ bool ContactsNameTable::add(ContactsNameTableRow entry)
bool ContactsNameTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM contact_name where _id = %lu;", id);
+ return db->execute("DELETE FROM contact_name where _id=" u32_ ";", id);
}
bool ContactsNameTable::update(ContactsNameTableRow entry)
{
- return db->execute("UPDATE contact_name SET contact_id = %lu, name_primary = '%q', name_alternative = '%q' "
- "WHERE _id = %lu;",
+ return db->execute("UPDATE contact_name SET contact_id=" u32_c "name_primary=" str_c "name_alternative=" str_
+ "WHERE _id=" u32_ ";",
entry.contactID,
entry.namePrimary.c_str(),
entry.nameAlternative.c_str(),
@@ 41,7 42,7 @@ bool ContactsNameTable::update(ContactsNameTableRow entry)
ContactsNameTableRow ContactsNameTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM contact_name WHERE _id= %lu;", id);
+ auto retQuery = db->query("SELECT * FROM contact_name WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return ContactsNameTableRow();
@@ 57,8 58,8 @@ ContactsNameTableRow ContactsNameTable::getById(uint32_t id)
std::vector<ContactsNameTableRow> ContactsNameTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery =
- db->query("SELECT * from contact_name ORDER BY name_alternative ASC LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query(
+ "SELECT * from contact_name ORDER BY name_alternative ASC LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNameTableRow>();
@@ 97,12 98,12 @@ std::vector<ContactsNameTableRow> ContactsNameTable::getLimitOffsetByField(uint3
return std::vector<ContactsNameTableRow>();
}
- auto retQuery =
- db->query("SELECT * from contact_name WHERE %q='%q' ORDER BY name_alternative LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ auto retQuery = db->query("SELECT * from contact_name WHERE %q=" str_ " ORDER BY name_alternative LIMIT " u32_
+ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNameTableRow>();
@@ 135,7 136,7 @@ uint32_t ContactsNameTable::count()
uint32_t ContactsNameTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM contact_name WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM contact_name WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
@@ 147,10 148,11 @@ uint32_t ContactsNameTable::countByFieldId(const char *field, uint32_t id)
std::vector<ContactsNameTableRow> ContactsNameTable::GetByName(const char *primaryName, const char *alternativeName)
{
- auto retQuery = db->query("SELECT * from contact_name WHERE name_primary='%q' AND name_alternative='%q' ORDER BY "
- "name_alternative LIMIT 1;",
- primaryName,
- alternativeName);
+ auto retQuery =
+ db->query("SELECT * from contact_name WHERE name_primary=" str_ " AND name_alternative=" str_ " ORDER BY "
+ "name_alternative LIMIT 1;",
+ primaryName,
+ alternativeName);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNameTableRow>();
M module-db/Tables/ContactsNumberTable.cpp => module-db/Tables/ContactsNumberTable.cpp +31 -27
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsNumberTable.hpp"
+#include "Common/Types.hpp"
ContactsNumberTable::ContactsNumberTable(Database *db) : Table(db)
{}
@@ 16,33 17,34 @@ bool ContactsNumberTable::create()
bool ContactsNumberTable::add(ContactsNumberTableRow entry)
{
- return db->execute("insert or ignore into contact_number (contact_id, number_user, number_e164, type) VALUES (%lu, "
- "'%q', '%q', %lu);",
- entry.contactID,
- entry.numberUser.c_str(),
- entry.numbere164.c_str(),
- entry.type);
+ return db->execute(
+ "insert or ignore into contact_number (contact_id, number_user, number_e164, type) VALUES (" u32_c str_c str_c
+ u32_ ");",
+ entry.contactID,
+ entry.numberUser.c_str(),
+ entry.numbere164.c_str(),
+ entry.type);
}
bool ContactsNumberTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM contact_number where _id = %u;", id);
+ return db->execute("DELETE FROM contact_number where _id=" u32_ ";", id);
}
bool ContactsNumberTable::update(ContactsNumberTableRow entry)
{
- return db->execute(
- "UPDATE contact_number SET contact_id = %lu, number_user = '%q', number_e164 = '%q', type = %lu WHERE _id=%lu;",
- entry.contactID,
- entry.numberUser.c_str(),
- entry.numbere164.c_str(),
- entry.type,
- entry.ID);
+ return db->execute("UPDATE contact_number SET contact_id=" u32_c "number_user=" str_c "number_e164=" str_c
+ "type=" u32_ " WHERE _id=" u32_ ";",
+ entry.contactID,
+ entry.numberUser.c_str(),
+ entry.numbere164.c_str(),
+ entry.type,
+ entry.ID);
}
ContactsNumberTableRow ContactsNumberTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM contact_number WHERE _id= %lu;", id);
+ auto retQuery = db->query("SELECT * FROM contact_number WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return ContactsNumberTableRow();
@@ 59,7 61,7 @@ ContactsNumberTableRow ContactsNumberTable::getById(uint32_t id)
std::vector<ContactsNumberTableRow> ContactsNumberTable::getByContactId(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM contact_number WHERE contact_id = %lu;", id);
+ auto retQuery = db->query("SELECT * FROM contact_number WHERE contact_id=" u32_ ";", id);
if (!retQuery || (retQuery->getRowCount() == 0U)) {
return {};
}
@@ 81,7 83,7 @@ std::vector<ContactsNumberTableRow> ContactsNumberTable::getByContactId(uint32_t
std::vector<ContactsNumberTableRow> ContactsNumberTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from contact_number LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query("SELECT * from contact_number LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNumberTableRow>();
@@ 107,10 109,11 @@ std::vector<ContactsNumberTableRow> ContactsNumberTable::getLimitOffset(const st
uint32_t limit)
{
const char lastCharacter = number.back();
- auto retQuery = db->query("SELECT * from contact_number WHERE number_user like '%%%c' LIMIT %lu OFFSET %lu;",
- lastCharacter,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * from contact_number WHERE number_user like '%%%c' LIMIT " u32_ " OFFSET " u32_ ";",
+ lastCharacter,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNumberTableRow>();
}
@@ 145,11 148,12 @@ std::vector<ContactsNumberTableRow> ContactsNumberTable::getLimitOffsetByField(u
return std::vector<ContactsNumberTableRow>();
}
- auto retQuery = db->query("SELECT * from contact_number WHERE %q='%q' ORDER BY number_user LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * from contact_number WHERE %q=" str_ " ORDER BY number_user LIMIT " u32_ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsNumberTableRow>();
@@ 183,7 187,7 @@ uint32_t ContactsNumberTable::count()
uint32_t ContactsNumberTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM contact_number WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM contact_number WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
M module-db/Tables/ContactsRingtonesTable.cpp => module-db/Tables/ContactsRingtonesTable.cpp +9 -7
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsRingtonesTable.hpp"
+#include "Common/Types.hpp"
ContactsRingtonesTable::ContactsRingtonesTable(Database *db) : Table(db)
{}
@@ 16,19 17,19 @@ bool ContactsRingtonesTable::create()
bool ContactsRingtonesTable::add(ContactsRingtonesTableRow entry)
{
- return db->execute("insert or ignore into contact_ringtones (contact_id, asset_path ) VALUES (%lu, '%q');",
+ return db->execute("insert or ignore into contact_ringtones (contact_id, asset_path ) VALUES (" u32_c str_ ");",
entry.contactID,
entry.assetPath.c_str());
}
bool ContactsRingtonesTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM contact_ringtones where _id = %u;", id);
+ return db->execute("DELETE FROM contact_ringtones where _id=" u32_ ";", id);
}
bool ContactsRingtonesTable::update(ContactsRingtonesTableRow entry)
{
- return db->execute("UPDATE contact_ringtones SET contact_id = %lu, asset_path = '%q' WHERE _id=%lu;",
+ return db->execute("UPDATE contact_ringtones SET contact_id=" u32_c "asset_path=" str_ " WHERE _id=" u32_ ";",
entry.contactID,
entry.assetPath.c_str(),
entry.ID);
@@ 36,7 37,7 @@ bool ContactsRingtonesTable::update(ContactsRingtonesTableRow entry)
ContactsRingtonesTableRow ContactsRingtonesTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM contact_ringtones WHERE _id= %lu;", id);
+ auto retQuery = db->query("SELECT * FROM contact_ringtones WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return ContactsRingtonesTableRow();
@@ 52,7 53,7 @@ ContactsRingtonesTableRow ContactsRingtonesTable::getById(uint32_t id)
std::vector<ContactsRingtonesTableRow> ContactsRingtonesTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
auto retQuery =
- db->query("SELECT * from contact_ringtones ORDER BY contact_id LIMIT %lu OFFSET %lu;", limit, offset);
+ db->query("SELECT * from contact_ringtones ORDER BY contact_id LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsRingtonesTableRow>();
@@ 85,7 86,8 @@ std::vector<ContactsRingtonesTableRow> ContactsRingtonesTable::getLimitOffsetByF
return std::vector<ContactsRingtonesTableRow>();
}
- auto retQuery = db->query("SELECT * from contact_ringtones WHERE %q='%q' ORDER BY contact_id LIMIT %lu OFFSET %lu;",
+ auto retQuery = db->query("SELECT * from contact_ringtones WHERE %q=" str_ " ORDER BY contact_id LIMIT " u32_
+ " OFFSET " u32_ ";",
fieldName.c_str(),
str,
limit,
@@ 121,7 123,7 @@ uint32_t ContactsRingtonesTable::count()
uint32_t ContactsRingtonesTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM contact_ringtones WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM contact_ringtones WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
M module-db/Tables/ContactsTable.cpp => module-db/Tables/ContactsTable.cpp +16 -15
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ContactsTable.hpp"
+#include "Common/Types.hpp"
#include <log/log.hpp>
#include <Utils.hpp>
@@ 17,15 18,14 @@ namespace ColumnName
namespace statements
{
- const auto selectWithoutTemp = "SELECT * FROM contacts WHERE _id= %lu"
- " AND "
+ const auto selectWithoutTemp = "SELECT * FROM contacts WHERE _id=" u32_ " AND "
" contacts._id NOT IN ( "
" SELECT cmg.contact_id "
" FROM contact_match_groups cmg, contact_groups cg "
" WHERE cmg.group_id = cg._id "
" AND cg.name = 'Temporary' "
" ) ";
- const auto selectWithTemp = "SELECT * FROM contacts WHERE _id= %lu";
+ const auto selectWithTemp = "SELECT * FROM contacts WHERE _id=" u32_ ";";
} // namespace statements
ContactsTable::ContactsTable(Database *db) : Table(db)
@@ 42,7 42,7 @@ bool ContactsTable::create()
bool ContactsTable::add(ContactsTableRow entry)
{
return db->execute("insert or ignore into contacts (name_id, numbers_id, ring_id, address_id, speeddial) "
- " VALUES (%lu, '%q', %lu, %lu, '%q');",
+ " VALUES (" u32_c str_c u32_c u32_c str_ ");",
entry.nameID,
entry.numbersID.c_str(),
entry.ringID,
@@ 52,18 52,18 @@ bool ContactsTable::add(ContactsTableRow entry)
bool ContactsTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM contacts where _id = %u;", id);
+ return db->execute("DELETE FROM contacts where _id=" u32_ ";", id);
}
bool ContactsTable::BlockByID(uint32_t id, bool shouldBeBlocked)
{
- return db->execute("UPDATE contacts SET blacklist=%lu WHERE _id=%lu", shouldBeBlocked ? 1 : 0, id);
+ return db->execute("UPDATE contacts SET blacklist=" u32_ " WHERE _id=" u32_ ";", shouldBeBlocked ? 1 : 0, id);
}
bool ContactsTable::update(ContactsTableRow entry)
{
- return db->execute("UPDATE contacts SET name_id = %lu, numbers_id = '%q', ring_id = %lu, address_id = %lu, "
- " speeddial = '%q' WHERE _id=%lu;",
+ return db->execute("UPDATE contacts SET name_id=" u32_c "numbers_id=" str_c "ring_id=" u32_c "address_id=" u32_c
+ "speeddial=" str_ " WHERE _id=" u32_ ";",
entry.nameID,
entry.numbersID.c_str(),
entry.ringID,
@@ 362,7 362,7 @@ std::vector<ContactsTableRow> ContactsTable::getLimitOffset(uint32_t offset, uin
" WHERE cmg.group_id = cg._id "
" AND cg.name = 'Temporary' "
" ) "
- "ORDER BY name_id LIMIT %lu OFFSET %lu;",
+ "ORDER BY name_id LIMIT " u32_ " OFFSET " u32_ ";",
limit,
offset);
@@ 401,11 401,12 @@ std::vector<ContactsTableRow> ContactsTable::getLimitOffsetByField(uint32_t offs
return std::vector<ContactsTableRow>();
}
- auto retQuery = db->query("SELECT * from contacts WHERE %q='%q' ORDER BY name_id LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * from contacts WHERE %q=" str_ " ORDER BY name_id LIMIT " u32_ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ContactsTableRow>();
@@ 446,7 447,7 @@ uint32_t ContactsTable::count()
uint32_t ContactsTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM contacts WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM contacts WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
D module-db/Tables/CountryCodesTable.cpp => module-db/Tables/CountryCodesTable.cpp +0 -45
@@ 1,45 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "CountryCodesTable.hpp"
-
-CountryCodesTable::CountryCodesTable(Database *db) : Table(db)
-{}
-
-CountryCodesTable::~CountryCodesTable()
-{}
-
-bool CountryCodesTable::create()
-{
- return db->execute(createTableQuery);
-}
-
-CodesTableRow CountryCodesTable::GetByMCC(uint32_t mcc)
-{
- auto retQuery = db->query("SELECT * FROM codes WHERE mcc= %lu LIMIT 1;", mcc);
-
- if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
- return CodesTableRow();
- }
-
- return CodesTableRow{
- (*retQuery)[0].getUInt32(), /* _id */
- (*retQuery)[1].getUInt32(), /* mcc */
- (*retQuery)[2].getUInt32(), /* mnc */
- (*retQuery)[3].getString(), /* iso */
- (*retQuery)[4].getString(), /* country name */
- (*retQuery)[5].getUInt32(), /* country code */
- (*retQuery)[5].getString() /* network name */
- };
-}
-
-uint32_t CountryCodesTable::count()
-{
- auto queryRet = db->query("SELECT COUNT(*) FROM codes;");
-
- if (!queryRet || queryRet->getRowCount() == 0) {
- return 0;
- }
-
- return uint32_t{(*queryRet)[0].getUInt32()};
-}
D module-db/Tables/CountryCodesTable.hpp => module-db/Tables/CountryCodesTable.hpp +0 -75
@@ 1,75 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-#include "Common/Common.hpp"
-#include "Database/Database.hpp"
-#include "Record.hpp"
-#include "Table.hpp"
-#include "utf8/UTF8.hpp"
-#include <string>
-
-struct CodesTableRow : public Record
-{
- uint32_t mcc;
- uint32_t mnc;
- std::string iso;
- std::string country;
- uint32_t country_code;
- std::string network;
-};
-
-enum CodesTableFields
-{
-};
-
-class CountryCodesTable : public Table<CodesTableRow, CodesTableFields>
-{
- public:
- CountryCodesTable(Database *db);
- virtual ~CountryCodesTable();
- bool create() override final;
- uint32_t count() override final;
- bool add(CodesTableRow entry) override final
- {
- return (true);
- }
- bool removeById(uint32_t id) override final
- {
- return (true);
- }
- bool update(CodesTableRow entry) override final
- {
- return (true);
- }
- CodesTableRow getById(uint32_t id) override final
- {
- return CodesTableRow();
- }
- std::vector<CodesTableRow> getLimitOffset(uint32_t offset, uint32_t limit) override final
- {
- return std::vector<CodesTableRow>();
- }
- std::vector<CodesTableRow> getLimitOffsetByField(uint32_t offset,
- uint32_t limit,
- CodesTableFields field,
- const char *str) override final
- {
- return std::vector<CodesTableRow>();
- }
- uint32_t countByFieldId(const char *field, uint32_t id) override final
- {
- return count();
- }
- CodesTableRow GetByMCC(uint32_t mcc);
-
- private:
- const char *createTableQuery = "CREATE TABLE IF NOT EXISTS codes("
- "_id INTEGER PRIMARY KEY,"
- "mcc INTEGER,"
- "mnc INTEGER,"
- "iso TEXT NOT NULL,"
- "country TEXT NOT NULL,"
- "country_code INTEGER,"
- "network TEXT NOT NULL);";
-};
M module-db/Tables/MultimediaFilesTable.cpp => module-db/Tables/MultimediaFilesTable.cpp +3 -8
@@ 2,17 2,12 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "MultimediaFilesTable.hpp"
-
+#include "Common/Types.hpp"
#include <Database/QueryResult.hpp>
#include <Utils.hpp>
#include <magic_enum.hpp>
#include <inttypes.h>
-#define u32_ "%" PRIu32
-#define u32_c "%" PRIu32 ","
-#define str_ "%Q"
-#define str_c "%Q,"
-
namespace db::multimedia_files
{
TableRow CreateTableRow(const QueryResult &result)
@@ 105,7 100,7 @@ namespace db::multimedia_files
bool MultimediaFilesTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM files WHERE _id = %lu;", id);
+ return db->execute("DELETE FROM files WHERE _id=" u32_ ";", id);
}
bool MultimediaFilesTable::removeByField(TableFields field, const char *str)
@@ 116,7 111,7 @@ namespace db::multimedia_files
return false;
}
- return db->execute("DELETE FROM files WHERE %q = %Q;", fieldName.c_str(), str);
+ return db->execute("DELETE FROM files WHERE %q=" str_ ";", fieldName.c_str(), str);
}
bool MultimediaFilesTable::removeAll()
M module-db/Tables/NotesTable.cpp => module-db/Tables/NotesTable.cpp +15 -14
@@ 2,7 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "NotesTable.hpp"
-#include <log/log.hpp>
+#include "Common/Types.hpp"
#include <string>
NotesTable::NotesTable(Database *db) : Table(db)
@@ 16,7 16,7 @@ bool NotesTable::create()
bool NotesTable::add(NotesTableRow entry)
{
return db->execute(
- "INSERT or ignore INTO notes ( date, snippet ) VALUES ( %lu, '%q' );", entry.date, entry.snippet.c_str());
+ "INSERT or ignore INTO notes ( date, snippet ) VALUES (" u32_c str_ ");", entry.date, entry.snippet.c_str());
}
bool NotesTable::removeAll()
@@ 26,7 26,7 @@ bool NotesTable::removeAll()
bool NotesTable::removeById(std::uint32_t id)
{
- return db->execute("DELETE FROM notes where _id = %lu;", id);
+ return db->execute("DELETE FROM notes where _id=" u32_ ";", id);
}
bool NotesTable::removeByField(NotesTableFields field, const char *str)
@@ 42,18 42,18 @@ bool NotesTable::removeByField(NotesTableFields field, const char *str)
default:
return false;
}
- return db->execute("DELETE FROM note where %q = '%q';", fieldName.c_str(), str);
+ return db->execute("DELETE FROM note where %q=" str_ ";", fieldName.c_str(), str);
}
bool NotesTable::update(NotesTableRow entry)
{
return db->execute(
- "UPDATE notes SET date = %lu, snippet = '%q' WHERE _id = %lu;", entry.date, entry.snippet.c_str(), entry.ID);
+ "UPDATE notes SET date=" u32_c "snippet=" str_ " WHERE _id=" u32_, entry.date, entry.snippet.c_str(), entry.ID);
}
NotesTableRow NotesTable::getById(std::uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM notes WHERE _id = %lu;", id);
+ auto retQuery = db->query("SELECT * FROM notes WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return NotesTableRow();
}
@@ 66,7 66,7 @@ NotesTableRow NotesTable::getById(std::uint32_t id)
std::vector<NotesTableRow> NotesTable::getLimitOffset(std::uint32_t offset, std::uint32_t limit)
{
- auto retQuery = db->query("SELECT * FROM notes ORDER BY date DESC LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query("SELECT * FROM notes ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<NotesTableRow>();
}
@@ 99,11 99,12 @@ std::vector<NotesTableRow> NotesTable::getLimitOffsetByField(std::uint32_t offse
return std::vector<NotesTableRow>();
}
- auto retQuery = db->query("SELECT * FROM notes WHERE %q='%q' ORDER BY date DESC LIMIT %lu OFFSET %lu;",
- fieldName.c_str(),
- str,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * FROM notes WHERE %q=" str_ " ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";",
+ fieldName.c_str(),
+ str,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<NotesTableRow>();
}
@@ 125,7 126,7 @@ std::pair<std::vector<NotesTableRow>, int> NotesTable::getByText(const std::stri
{
int count = 0;
- auto queryRet = db->query("SELECT COUNT(*), INSTR(snippet,'%q') pos FROM notes WHERE pos > 0;", text.c_str());
+ auto queryRet = db->query("SELECT COUNT(*), INSTR(snippet," str_ ") pos FROM notes WHERE pos > 0;", text.c_str());
if (queryRet && queryRet->getRowCount() != 0) {
count = (*queryRet)[0].getUInt32();
}
@@ 162,7 163,7 @@ std::uint32_t NotesTable::count()
std::uint32_t NotesTable::countByFieldId(const char *field, std::uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM notes WHERE %q = %lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM notes WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
}
M module-db/Tables/NotificationsTable.cpp => module-db/Tables/NotificationsTable.cpp +8 -8
@@ 2,10 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "NotificationsTable.hpp"
+#include "Common/Types.hpp"
#include "Database/Database.hpp"
#include <log/log.hpp>
-#include <Utils.hpp>
#include <cassert>
NotificationsTable::NotificationsTable(Database *db) : Table(db)
@@ 18,7 18,7 @@ bool NotificationsTable::create()
bool NotificationsTable::add(NotificationsTableRow entry)
{
- return db->execute("INSERT or IGNORE INTO notifications (key, value, contact_id) VALUES (%lu, %lu, %lu);",
+ return db->execute("INSERT or IGNORE INTO notifications (key, value, contact_id) VALUES (" u32_c u32_c u32_ ");",
entry.key,
entry.value,
entry.contactID);
@@ 26,7 26,7 @@ bool NotificationsTable::add(NotificationsTableRow entry)
bool NotificationsTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM notifications where _id = %lu;", id);
+ return db->execute("DELETE FROM notifications where _id=" u32_ ";", id);
}
bool NotificationsTable::removeByField(NotificationsTableFields field, const char *str)
@@ 39,12 39,12 @@ bool NotificationsTable::removeByField(NotificationsTableFields field, const cha
break;
}
- return db->execute("DELETE FROM notifications where %q = '%q';", fieldName.c_str(), str);
+ return db->execute("DELETE FROM notifications where %q=" str_ ";", fieldName.c_str(), str);
}
bool NotificationsTable::update(NotificationsTableRow entry)
{
- return db->execute("UPDATE notifications SET key = %lu, value = %lu, contact_id = %lu WHERE _id = %lu;",
+ return db->execute("UPDATE notifications SET key=" u32_c "value=" u32_c "contact_id=" u32_ " WHERE _id=" u32_ ";",
entry.key,
entry.value,
entry.contactID,
@@ 53,7 53,7 @@ bool NotificationsTable::update(NotificationsTableRow entry)
NotificationsTableRow NotificationsTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM notifications WHERE _id= %u;", id);
+ auto retQuery = db->query("SELECT * FROM notifications WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return NotificationsTableRow();
@@ 71,7 71,7 @@ NotificationsTableRow NotificationsTable::getById(uint32_t id)
NotificationsTableRow NotificationsTable::getByKey(uint32_t key)
{
- auto retQuery = db->query("SELECT * FROM notifications WHERE key= %u;", key);
+ auto retQuery = db->query("SELECT * FROM notifications WHERE key=" u32_ ";", key);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return NotificationsTableRow();
@@ 89,7 89,7 @@ NotificationsTableRow NotificationsTable::getByKey(uint32_t key)
std::vector<NotificationsTableRow> NotificationsTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from notifications LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query("SELECT * from notifications LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<NotificationsTableRow>();
M module-db/Tables/SMSTable.cpp => module-db/Tables/SMSTable.cpp +39 -30
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SMSTable.hpp"
+#include "Common/Types.hpp"
#include <log/log.hpp>
SMSTable::SMSTable(Database *db) : Table(db)
@@ 15,7 16,7 @@ bool SMSTable::create()
bool SMSTable::add(SMSTableRow entry)
{
return db->execute("INSERT or ignore INTO sms ( thread_id,contact_id, date, error_code, body, "
- "type ) VALUES (%lu,%lu,%lu,0,'%q',%d);",
+ "type ) VALUES (" u32_c u32_c u32_c "0," str_c u32_ ");",
entry.threadID,
entry.contactID,
entry.date,
@@ 25,7 26,7 @@ bool SMSTable::add(SMSTableRow entry)
bool SMSTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM sms where _id = %u;", id);
+ return db->execute("DELETE FROM sms where _id=" u32_ ";", id);
}
bool SMSTable::removeByField(SMSTableFields field, const char *str)
@@ 48,13 49,13 @@ bool SMSTable::removeByField(SMSTableFields field, const char *str)
return false;
}
- return db->execute("DELETE FROM sms where %q = '%q';", fieldName.c_str(), str);
+ return db->execute("DELETE FROM sms where %q=" u32_ ";", fieldName.c_str(), str);
}
bool SMSTable::update(SMSTableRow entry)
{
- return db->execute("UPDATE sms SET thread_id = %lu, contact_id = %lu ,date = %lu, error_code = 0, "
- "body = '%q', type =%d WHERE _id=%lu;",
+ return db->execute("UPDATE sms SET thread_id=" u32_c "contact_id=" u32_c "date=" u32_c "error_code=0,"
+ "body=" str_c "type=" u32_ " WHERE _id=" u32_ ";",
entry.threadID,
entry.contactID,
entry.date,
@@ 65,7 66,7 @@ bool SMSTable::update(SMSTableRow entry)
SMSTableRow SMSTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM sms WHERE _id= %u;", id);
+ auto retQuery = db->query("SELECT * FROM sms WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return SMSTableRow();
@@ 84,7 85,7 @@ SMSTableRow SMSTable::getById(uint32_t id)
std::vector<SMSTableRow> SMSTable::getByContactId(uint32_t contactId)
{
- auto retQuery = db->query("SELECT * FROM sms WHERE contact_id= %u;", contactId);
+ auto retQuery = db->query("SELECT * FROM sms WHERE contact_id=" u32_ ";", contactId);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<SMSTableRow>();
@@ 108,10 109,11 @@ std::vector<SMSTableRow> SMSTable::getByContactId(uint32_t contactId)
}
std::vector<SMSTableRow> SMSTable::getByThreadId(uint32_t threadId, uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * FROM sms WHERE thread_id= %u", threadId);
+ auto retQuery = db->query("SELECT * FROM sms WHERE thread_id=" u32_ ";", threadId);
if (limit != 0) {
- retQuery = db->query("SELECT * FROM sms WHERE thread_id= %u LIMIT %u OFFSET %u", threadId, limit, offset);
+ retQuery = db->query(
+ "SELECT * FROM sms WHERE thread_id=" u32_ " LIMIT " u32_ " OFFSET " u32_ ";", threadId, limit, offset);
}
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
@@ 139,14 141,15 @@ std::vector<SMSTableRow> SMSTable::getByThreadIdWithoutDraftWithEmptyInput(uint3
uint32_t offset,
uint32_t limit)
{
- auto retQuery = db->query("SELECT * FROM sms WHERE thread_id= %u AND type != %u UNION ALL SELECT 0 as _id, 0 as "
- "thread_id, 0 as contact_id, 0 as "
- "date, 0 as error_code, 0 as body, %u as type LIMIT %u OFFSET %u",
- threadId,
- SMSType::DRAFT,
- SMSType::INPUT,
- limit,
- offset);
+ auto retQuery =
+ db->query("SELECT * FROM sms WHERE thread_id=" u32_ " AND type!=" u32_ " UNION ALL SELECT 0 as _id, 0 as "
+ "thread_id, 0 as contact_id, 0 as "
+ "date, 0 as error_code, 0 as body, " u32_ " as type LIMIT " u32_ " OFFSET " u32_,
+ threadId,
+ SMSType::DRAFT,
+ SMSType::INPUT,
+ limit,
+ offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<SMSTableRow>();
@@ 171,7 174,8 @@ std::vector<SMSTableRow> SMSTable::getByThreadIdWithoutDraftWithEmptyInput(uint3
uint32_t SMSTable::countWithoutDraftsByThreadId(uint32_t threadId)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM sms WHERE thread_id= %u AND type != %u;", threadId, SMSType::DRAFT);
+ auto queryRet =
+ db->query("SELECT COUNT(*) FROM sms WHERE thread_id=" u32_ " AND type!=" u32_ ";", threadId, SMSType::DRAFT);
if (queryRet == nullptr || queryRet->getRowCount() == 0) {
return 0;
@@ 182,8 186,10 @@ uint32_t SMSTable::countWithoutDraftsByThreadId(uint32_t threadId)
SMSTableRow SMSTable::getDraftByThreadId(uint32_t threadId)
{
- auto retQuery = db->query(
- "SELECT * FROM sms WHERE thread_id= %u AND type = %u ORDER BY date DESC LIMIT 1;", threadId, SMSType::DRAFT);
+ auto retQuery =
+ db->query("SELECT * FROM sms WHERE thread_id=" u32_ " AND type=" u32_ " ORDER BY date DESC LIMIT 1;",
+ threadId,
+ SMSType::DRAFT);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return SMSTableRow();
@@ 203,7 209,7 @@ SMSTableRow SMSTable::getDraftByThreadId(uint32_t threadId)
std::vector<SMSTableRow> SMSTable::getByText(std::string text)
{
- auto retQuery = db->query("SELECT *, INSTR(body,'%q') pos FROM sms WHERE pos > 0;", text.c_str());
+ auto retQuery = db->query("SELECT *, INSTR(body," str_ ") pos FROM sms WHERE pos > 0;", text.c_str());
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<SMSTableRow>();
@@ 228,8 234,8 @@ std::vector<SMSTableRow> SMSTable::getByText(std::string text)
std::vector<SMSTableRow> SMSTable::getByText(std::string text, uint32_t threadId)
{
- auto retQuery =
- db->query("SELECT *, INSTR(body,'%q') pos FROM sms WHERE pos > 0 AND thread_id=%u;", text.c_str(), threadId);
+ auto retQuery = db->query(
+ "SELECT *, INSTR(body," str_ ") pos FROM sms WHERE pos > 0 AND thread_id=" u32_ ";", text.c_str(), threadId);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return {};
}
@@ 251,7 257,7 @@ std::vector<SMSTableRow> SMSTable::getByText(std::string text, uint32_t threadId
std::vector<SMSTableRow> SMSTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from sms ORDER BY date DESC LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery = db->query("SELECT * from sms ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<SMSTableRow>();
@@ 295,7 301,7 @@ std::vector<SMSTableRow> SMSTable::getLimitOffsetByField(uint32_t offset,
return std::vector<SMSTableRow>();
}
- auto retQuery = db->query("SELECT * from sms WHERE %q='%q' ORDER BY date DESC LIMIT %lu OFFSET %lu;",
+ auto retQuery = db->query("SELECT * from sms WHERE %q=" str_ " ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";",
fieldName.c_str(),
str,
limit,
@@ 335,7 341,7 @@ uint32_t SMSTable::count()
uint32_t SMSTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM sms WHERE %q=%lu;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM sms WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
@@ 347,12 353,15 @@ uint32_t SMSTable::countByFieldId(const char *field, uint32_t id)
std::pair<uint32_t, std::vector<SMSTableRow>> SMSTable::getManyByType(SMSType type, uint32_t offset, uint32_t limit)
{
auto ret = std::pair<uint32_t, std::vector<SMSTableRow>>{0, {}};
- auto count = db->query("SELECT COUNT (*) from sms WHERE type='%lu';", type);
+ auto count = db->query("SELECT COUNT (*) from sms WHERE type=" u32_ ";", type);
ret.first = count == nullptr ? 0 : (*count)[0].getUInt32();
if (ret.first != 0) {
- limit = limit == 0 ? ret.first : limit; // no limit intended
- auto retQuery = db->query(
- "SELECT * from sms WHERE type='%lu' ORDER BY date ASC LIMIT %lu OFFSET %lu;", type, limit, offset);
+ limit = limit == 0 ? ret.first : limit; // no limit intended
+ auto retQuery =
+ db->query("SELECT * from sms WHERE type=" u32_ " ORDER BY date ASC LIMIT " u32_ " OFFSET " u32_ ";",
+ type,
+ limit,
+ offset);
if (retQuery == nullptr || retQuery->getRowCount() == 0) {
ret.second = {};
M module-db/Tables/ThreadsTable.cpp => module-db/Tables/ThreadsTable.cpp +28 -27
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ThreadsTable.hpp"
+#include "Common/Types.hpp"
#include <log/log.hpp>
ThreadsTable::ThreadsTable(Database *db) : Table(db)
@@ 17,7 18,7 @@ bool ThreadsTable::add(ThreadsTableRow entry)
return db->execute(
"INSERT or ignore INTO threads ( date, msg_count, read, contact_id, number_id, snippet, last_dir ) VALUES "
- "( %lu, %lu, %lu, %lu, %lu, '%q', %lu );",
+ "(" u32_c u32_c u32_c u32_c u32_c str_c u32_ ");",
entry.date,
entry.msgCount,
entry.unreadMsgCount,
@@ 29,14 30,13 @@ bool ThreadsTable::add(ThreadsTableRow entry)
bool ThreadsTable::removeById(uint32_t id)
{
- return db->execute("DELETE FROM threads where _id = %u;", id);
+ return db->execute("DELETE FROM threads where _id= " u32_ ";", id);
}
bool ThreadsTable::update(ThreadsTableRow entry)
{
- return db->execute("UPDATE threads SET date = %lu, msg_count = %lu ,read = %lu, contact_id = %lu, number_id = %lu, "
- "snippet = '%q', "
- "last_dir = %lu WHERE _id=%lu;",
+ return db->execute("UPDATE threads SET date=" u32_c "msg_count=" u32_c "read=" u32_c "contact_id=" u32_c
+ "number_id=" u32_c "snippet=" str_c "last_dir=" u32_ " WHERE _id=" u32_ ";",
entry.date,
entry.msgCount,
entry.unreadMsgCount,
@@ 49,7 49,7 @@ bool ThreadsTable::update(ThreadsTableRow entry)
ThreadsTableRow ThreadsTable::getById(uint32_t id)
{
- auto retQuery = db->query("SELECT * FROM threads WHERE _id= %u;", id);
+ auto retQuery = db->query("SELECT * FROM threads WHERE _id=" u32_ ";", id);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return ThreadsTableRow();
@@ 86,7 86,8 @@ void fillRetQuery(std::vector<ThreadsTableRow> &ret, const std::unique_ptr<Query
std::vector<ThreadsTableRow> ThreadsTable::getLimitOffset(uint32_t offset, uint32_t limit)
{
- auto retQuery = db->query("SELECT * from threads ORDER BY date DESC LIMIT %lu OFFSET %lu;", limit, offset);
+ auto retQuery =
+ db->query("SELECT * from threads ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";", limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return std::vector<ThreadsTableRow>();
@@ 171,7 172,7 @@ uint32_t ThreadsTable::count(EntryState state)
uint32_t ThreadsTable::countByFieldId(const char *field, uint32_t id)
{
- auto queryRet = db->query("SELECT COUNT(*) FROM threads WHERE %q=%u;", field, id);
+ auto queryRet = db->query("SELECT COUNT(*) FROM threads WHERE %q=" u32_ ";", field, id);
if ((queryRet == nullptr) || (queryRet->getRowCount() == 0)) {
return 0;
@@ 184,26 185,26 @@ std::pair<uint32_t, std::vector<ThreadsTableRow>> ThreadsTable::getBySMSQuery(st
uint32_t offset,
uint32_t limit)
{
- auto ret = std::pair<uint32_t, std::vector<ThreadsTableRow>>{0, {}};
- auto count_ret = db->query("SELECT COUNT (*) from sms WHERE sms.body like \'%%%q%%\'", text.c_str());
- ret.first = count_ret == nullptr ? 0 : (*count_ret)[0].getUInt32();
-
- if (ret.first != 0) {
- auto retQuery =
- db->query("SELECT * from sms WHERE sms.body like \'%%%q%%\' ORDER BY date DESC LIMIT %lu OFFSET %lu;",
- text.c_str(),
- limit,
- offset);
-
- if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
- ret.second = {};
- }
- else {
- fillRetQuery(ret.second, retQuery);
- }
+ const auto totalCountQuery =
+ db->query("SELECT COUNT(*) from sms INNER JOIN threads ON sms.thread_id=threads._id where sms.body "
+ "like \'%%%q%%\'",
+ text.c_str());
+
+ if ((totalCountQuery == nullptr) || (totalCountQuery->getRowCount() == 0)) {
+ return {};
}
- else {
- ret.second = {};
+
+ const auto retQuery = db->query("SELECT * from sms INNER JOIN threads ON sms.thread_id=threads._id where sms.body "
+ "like \'%%%q%%\' ORDER BY date DESC LIMIT " u32_ " OFFSET " u32_ ";",
+ text.c_str(),
+ limit,
+ offset);
+
+ if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
+ return {};
}
+
+ auto ret = std::pair<uint32_t, std::vector<ThreadsTableRow>>{(*totalCountQuery)[0].getUInt32(), {}};
+ fillRetQuery(ret.second, retQuery);
return ret;
}
R module-db/Databases/CalllogDB.cpp => module-db/databases/CalllogDB.cpp +0 -0
R module-db/Databases/CalllogDB.hpp => module-db/databases/CalllogDB.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once
#include "Database/Database.hpp"
-#include "../Tables/CalllogTable.hpp"
+#include "module-db/Tables/CalllogTable.hpp"
class CalllogDB : public Database
{
R module-db/Databases/ContactsDB.cpp => module-db/databases/ContactsDB.cpp +0 -0
R module-db/Databases/ContactsDB.hpp => module-db/databases/ContactsDB.hpp +7 -7
@@ 3,13 3,13 @@
#pragma once
-#include <Database/Database.hpp>
-#include <Tables/ContactsTable.hpp>
-#include <Tables/ContactsNameTable.hpp>
-#include <Tables/ContactsNumberTable.hpp>
-#include <Tables/ContactsRingtonesTable.hpp>
-#include <Tables/ContactsAddressTable.hpp>
-#include <Tables/ContactsGroups.hpp>
+#include "module-db/Database/Database.hpp"
+#include "module-db/Tables/ContactsTable.hpp"
+#include "module-db/Tables/ContactsNameTable.hpp"
+#include "module-db/Tables/ContactsNumberTable.hpp"
+#include "module-db/Tables/ContactsRingtonesTable.hpp"
+#include "module-db/Tables/ContactsAddressTable.hpp"
+#include "module-db/Tables/ContactsGroups.hpp"
class ContactsDB : public Database
{
R module-db/Databases/EventsDB.cpp => module-db/databases/EventsDB.cpp +0 -0
R module-db/Databases/EventsDB.hpp => module-db/databases/EventsDB.hpp +0 -0
R module-db/Databases/MultimediaFilesDB.cpp => module-db/databases/MultimediaFilesDB.cpp +0 -0
R module-db/Databases/MultimediaFilesDB.hpp => module-db/databases/MultimediaFilesDB.hpp +0 -0
R module-db/Databases/NotesDB.cpp => module-db/databases/NotesDB.cpp +0 -0
R module-db/Databases/NotesDB.hpp => module-db/databases/NotesDB.hpp +1 -1
@@ 4,7 4,7 @@
#pragma once
#include "Database/Database.hpp"
-#include "../Tables/NotesTable.hpp"
+#include "module-db/Tables/NotesTable.hpp"
class NotesDB : public Database
{
R module-db/Databases/NotificationsDB.cpp => module-db/databases/NotificationsDB.cpp +0 -0
R module-db/Databases/NotificationsDB.hpp => module-db/databases/NotificationsDB.hpp +0 -0
R module-db/Databases/SmsDB.cpp => module-db/databases/SmsDB.cpp +0 -0
R module-db/Databases/SmsDB.hpp => module-db/databases/SmsDB.hpp +3 -3
@@ 4,9 4,9 @@
#pragma once
#include "Database/Database.hpp"
-#include "../Tables/SMSTable.hpp"
-#include "../Tables/ThreadsTable.hpp"
-#include "../Tables/SMSTemplateTable.hpp"
+#include "module-db/Tables/SMSTable.hpp"
+#include "module-db/Tables/ThreadsTable.hpp"
+#include "module-db/Tables/SMSTemplateTable.hpp"
class SmsDB : public Database
{
R image/user/db/events_001.sql => module-db/databases/scripts/events_001.sql +0 -0
R image/user/db/multimedia_001.sql => module-db/databases/scripts/multimedia_001.sql +0 -0
M module-db/tests/AlarmEventRecord_tests.cpp => module-db/tests/AlarmEventRecord_tests.cpp +4 -15
@@ 1,10 1,9 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
-
+#include <Helpers.hpp>
#include <Database/Database.hpp>
-#include <Databases/EventsDB.hpp>
+#include <databases/EventsDB.hpp>
#include <Interface/AlarmEventRecord.hpp>
#include <queries/alarm_events/QueryAlarmEventsAdd.hpp>
#include <queries/alarm_events/QueryAlarmEventsEdit.hpp>
@@ 17,7 16,6 @@
#include <algorithm>
#include <cstdint>
-#include <cstdio>
#include <cstring>
#include <filesystem>
@@ 34,15 32,8 @@ TEST_CASE("AlarmEventRecord queries tests")
constexpr auto testEnabled = true;
constexpr auto testSnoozeDuration = 15;
- Database::initialize();
-
- const auto eventsPath = (std::filesystem::path{"sys/user"} / "events.db");
- RemoveDbFiles(eventsPath.stem());
-
- auto eventsDB = EventsDB(eventsPath.c_str());
- REQUIRE(eventsDB.isInitialized());
-
- AlarmEventRecordInterface alarmEventRecordInterface(&eventsDB);
+ db::tests::DatabaseUnderTest<EventsDB> db{"events.db", db::tests::getScriptsPath()};
+ AlarmEventRecordInterface alarmEventRecordInterface(&db.get());
auto getQuery = [&](uint32_t id,
std::chrono::hours hour,
@@ 260,8 251,6 @@ TEST_CASE("AlarmEventRecord queries tests")
REQUIRE(retAlarmEvents[1].enabled);
REQUIRE(retAlarmEvents[2].enabled);
}
-
- Database::deinitialize();
}
TEST_CASE("AlarmEventRecord recurrence generation tests")
M module-db/tests/CMakeLists.txt => module-db/tests/CMakeLists.txt +7 -5
@@ 1,3 1,9 @@
+add_library(module-db-test_helpers Helpers.cpp)
+add_library(module-db::test::helpers ALIAS module-db-test_helpers)
+target_link_libraries(module-db-test_helpers PRIVATE module-db)
+target_include_directories(module-db-test_helpers PUBLIC . )
+
+
add_catch2_executable(
NAME
db
@@ 12,7 18,6 @@ add_catch2_executable(
ContactsRecord_tests.cpp
ContactsRingtonesTable_tests.cpp
ContactsTable_tests.cpp
- DbInitializer.cpp
MultimediaFilesTable_tests.cpp
NotesRecord_tests.cpp
NotesTable_tests.cpp
@@ 25,12 30,9 @@ add_catch2_executable(
SMSTemplateTable_tests.cpp
ThreadRecord_tests.cpp
ThreadsTable_tests.cpp
- common.cpp
LIBS
- module-sys
+ module-db::test::helpers
module-db
json::json
- USE_FS
)
-add_subdirectory(test-initializer)
M module-db/tests/CalllogRecord_tests.cpp => module-db/tests/CalllogRecord_tests.cpp +5 -22
@@ 3,34 3,19 @@
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Interface/CalllogRecord.hpp"
#include "Database/Database.hpp"
-#include "Databases/CalllogDB.hpp"
+#include "module-db/databases/CalllogDB.hpp"
-#include <cstdint>
#include <cstring>
#include <filesystem>
#include <algorithm>
-#include <iostream>
TEST_CASE("Calllog Record tests")
{
- Database::initialize();
-
- const auto calllogPath = (std::filesystem::path{"sys/user"} / "calllog.db");
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(calllogPath)) {
- REQUIRE(std::filesystem::remove(calllogPath));
- }
- if (std::filesystem::exists(contactsPath)) {
- REQUIRE(std::filesystem::remove(contactsPath));
- }
-
- CalllogDB calllogDb(calllogPath.c_str());
- ContactsDB contactsDb(contactsPath.c_str());
-
- REQUIRE(calllogDb.isInitialized());
- REQUIRE(contactsDb.isInitialized());
+ db::tests::DatabaseUnderTest<CalllogDB> calllogDb{"calllog.db", db::tests::getPurePhoneScriptsPath()};
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
SECTION("Default Constructor")
{
@@ 44,7 29,7 @@ TEST_CASE("Calllog Record tests")
REQUIRE(testRec.isRead == true);
}
- CalllogRecordInterface calllogRecordInterface(&calllogDb, &contactsDb);
+ CalllogRecordInterface calllogRecordInterface(&calllogDb.get(), &contactsDb.get());
CalllogRecord testRec;
testRec.presentation = PresentationType::PR_ALLOWED;
testRec.date = 100;
@@ 181,6 166,4 @@ TEST_CASE("Calllog Record tests")
REQUIRE(calllogRecordInterface.GetCount(EntryState::UNREAD) == 0);
REQUIRE(calllogRecordInterface.GetCount(EntryState::READ) == 4);
}
-
- Database::deinitialize();
}
M module-db/tests/CalllogTable_tests.cpp => module-db/tests/CalllogTable_tests.cpp +4 -16
@@ 2,30 2,20 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-
-#include "Database/Database.hpp"
-#include "Databases/CalllogDB.hpp"
+#include "Helpers.hpp"
+#include "module-db/databases/CalllogDB.hpp"
#include "Tables/CalllogTable.hpp"
#include <cstdint>
#include <string>
#include <algorithm>
-#include <filesystem>
TEST_CASE("Calllog Table tests")
{
- Database::initialize();
-
- const auto calllogPath = (std::filesystem::path{"sys/user"} / "calllog.db");
- if (std::filesystem::exists(calllogPath)) {
- REQUIRE(std::filesystem::remove(calllogPath));
- }
+ db::tests::DatabaseUnderTest<CalllogDB> calllogDb{"calllog.db", db::tests::getPurePhoneScriptsPath()};
- CalllogDB calllogDb{calllogPath.c_str()};
- REQUIRE(calllogDb.isInitialized());
-
- auto &callsTbl = calllogDb.calls;
+ auto &callsTbl = calllogDb.get().calls;
SECTION("Default Constructor")
{
@@ 164,6 154,4 @@ TEST_CASE("Calllog Table tests")
REQUIRE(callsTbl.count(EntryState::UNREAD) == 0);
REQUIRE(callsTbl.count(EntryState::READ) == 4);
}
-
- Database::deinitialize();
}
M module-db/tests/ContactGroups_tests.cpp => module-db/tests/ContactGroups_tests.cpp +14 -29
@@ 1,18 1,13 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
-#include <Databases/ContactsDB.hpp>
+#include "module-db/databases/ContactsDB.hpp"
#include <Tables/ContactsTable.hpp>
#include <Tables/ContactsGroups.hpp>
-#include <filesystem>
-
-#include <iomanip>
-#include <sstream>
-
namespace consts
{
uint32_t favouritesId = 1;
@@ 25,16 20,8 @@ void addSomeContacts(ContactsDB &contactsDb);
TEST_CASE("Contact Groups tests")
{
- INFO("sqlite Init");
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDb{contactsPath.c_str()};
- INFO("contactDB init");
- REQUIRE(contactDb.isInitialized());
- ContactsGroupsTable contactGroupsTable = ContactsGroupsTable(&contactDb);
- INFO("Create groups table");
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
+ ContactsGroupsTable contactGroupsTable = ContactsGroupsTable(&contactsDb.get());
REQUIRE(contactGroupsTable.create());
SECTION("Adding checking standard groups")
@@ 108,16 95,16 @@ TEST_CASE("Contact Groups tests")
REQUIRE(someGroups[9].ID == 17);
INFO("Adding some contacts");
- addSomeContacts(contactDb);
+ addSomeContacts(contactsDb.get());
}
SECTION("Update Groups")
{
- addSomeContacts(contactDb);
+ addSomeContacts(contactsDb.get());
- ContactsGroupsTableRow favouritesGroup(contactGroupsTable.getById(contactDb.favouritesGroupId()));
- ContactsGroupsTableRow iceGroup(contactGroupsTable.getById(contactDb.iceGroupId()));
- ContactsGroupsTableRow blockedGroup(contactGroupsTable.getById(contactDb.blockedGroupId()));
+ ContactsGroupsTableRow favouritesGroup(contactGroupsTable.getById(contactGroupsTable.favouritesId()));
+ ContactsGroupsTableRow iceGroup(contactGroupsTable.getById(contactGroupsTable.iceId()));
+ ContactsGroupsTableRow blockedGroup(contactGroupsTable.getById(contactGroupsTable.blockedId()));
ContactsGroupsTableRow familyGroup("Family");
ContactsGroupsTableRow friendsGroup("Friends");
ContactsGroupsTableRow workGroup("Work");
@@ 131,13 118,13 @@ TEST_CASE("Contact Groups tests")
workGroup.ID = contactGroupsTable.getId(workGroup.name);
// adding contact to some groups
- contactGroupsTable.addContactToGroup(1, contactDb.favouritesGroupId());
- contactGroupsTable.addContactToGroup(1, contactDb.iceGroupId());
- contactGroupsTable.addContactToGroup(1, contactDb.blockedGroupId());
+ contactGroupsTable.addContactToGroup(1, contactGroupsTable.favouritesId());
+ contactGroupsTable.addContactToGroup(1, contactGroupsTable.iceId());
+ contactGroupsTable.addContactToGroup(1, contactGroupsTable.blockedId());
contactGroupsTable.addContactToGroup(1, familyGroup.ID);
contactGroupsTable.addContactToGroup(1, workGroup.ID);
- // checking if adding was sucessfull
+ // checking if adding was successful
REQUIRE(contactGroupsTable.getGroupsForContact(1).size() == 5);
// creating new groups set
@@ 154,7 141,7 @@ TEST_CASE("Contact Groups tests")
auto checkGroupsSet = contactGroupsTable.getGroupsForContact(1);
auto checkEnd = checkGroupsSet.end();
- // checking if update was successfull
+ // checking if update was successful
REQUIRE(checkGroupsSet.size() == 4);
REQUIRE(checkGroupsSet.find(blockedGroup) != checkEnd);
REQUIRE(checkGroupsSet.find(familyGroup) != checkEnd);
@@ 164,8 151,6 @@ TEST_CASE("Contact Groups tests")
REQUIRE(checkGroupsSet.find(favouritesGroup) == checkEnd);
REQUIRE(checkGroupsSet.find(iceGroup) == checkEnd);
}
-
- Database::deinitialize();
}
void addSomeContacts(ContactsDB &contactsDb)
M module-db/tests/ContactsAddressTable_tests.cpp => module-db/tests/ContactsAddressTable_tests.cpp +29 -39
@@ 2,21 2,12 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-
-#include "Databases/ContactsDB.hpp"
-#include <filesystem>
+#include "Helpers.hpp"
+#include "module-db/databases/ContactsDB.hpp"
TEST_CASE("Contacts address Table tests")
{
- Database::initialize();
-
- const auto callogPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(callogPath)) {
- REQUIRE(std::filesystem::remove(callogPath));
- }
-
- ContactsDB contactsdb{callogPath.c_str()};
- REQUIRE(contactsdb.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
ContactsAddressTableRow testRow1 = {Record(DB_ID_NONE),
.contactID = 0,
@@ 24,71 15,70 @@ TEST_CASE("Contacts address Table tests")
.note = "Test note",
.mail = "test@mudita.com"};
- const auto contactsCount = contactsdb.address.count() + 1;
+ const auto contactsCount = contactsDb.get().address.count() + 1;
// clear contacts table
for (std::uint32_t id = 1; id <= contactsCount; id++) {
- REQUIRE(contactsdb.address.removeById(id));
+ REQUIRE(contactsDb.get().address.removeById(id));
}
// add 4 elements into table
- REQUIRE(contactsdb.address.add(testRow1));
- REQUIRE(contactsdb.address.add(testRow1));
- REQUIRE(contactsdb.address.add(testRow1));
- REQUIRE(contactsdb.address.add(testRow1));
+ REQUIRE(contactsDb.get().address.add(testRow1));
+ REQUIRE(contactsDb.get().address.add(testRow1));
+ REQUIRE(contactsDb.get().address.add(testRow1));
+ REQUIRE(contactsDb.get().address.add(testRow1));
// Table should have 4 elements
- REQUIRE(contactsdb.address.count() == 4);
+ REQUIRE(contactsDb.get().address.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.note = "Modified test note";
- REQUIRE(contactsdb.address.update(testRow1));
+ REQUIRE(contactsDb.get().address.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = contactsdb.address.getById(4);
+ auto sms = contactsDb.get().address.getById(4);
REQUIRE(sms.note == testRow1.note);
- // Get table row using invalid ID(should return empty contactsdb.addressRow)
- auto smsFailed = contactsdb.address.getById(100);
+ // Get table row using invalid ID(should return empty contactsDb.get().addressRow)
+ auto smsFailed = contactsDb.get().address.getById(100);
REQUIRE(smsFailed.note == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = contactsdb.address.getLimitOffset(0, 4);
+ auto retOffsetLimit = contactsDb.get().address.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(contactsdb.address.getLimitOffsetByField(0, 4, ContactAddressTableFields::Mail, "test@mudita.com").size() ==
- 4);
+ REQUIRE(contactsDb.get()
+ .address.getLimitOffsetByField(0, 4, ContactAddressTableFields::Mail, "test@mudita.com")
+ .size() == 4);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = contactsdb.address.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = contactsDb.get().address.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = contactsdb.address.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = contactsDb.get().address.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(contactsdb.address.countByFieldId("contact_id", 0) == 4);
+ REQUIRE(contactsDb.get().address.countByFieldId("contact_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(contactsdb.address.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(contactsDb.get().address.countByFieldId("invalid_field", 0) == 0);
// Remove existing element
- REQUIRE(contactsdb.address.removeById(2));
+ REQUIRE(contactsDb.get().address.removeById(2));
// Table should have now 3 elements
- REQUIRE(contactsdb.address.count() == 3);
+ REQUIRE(contactsDb.get().address.count() == 3);
// Remove non existing element
- REQUIRE(contactsdb.address.removeById(100));
+ REQUIRE(contactsDb.get().address.removeById(100));
// Remove all elements from table
- REQUIRE(contactsdb.address.removeById(1));
- REQUIRE(contactsdb.address.removeById(3));
- REQUIRE(contactsdb.address.removeById(4));
+ REQUIRE(contactsDb.get().address.removeById(1));
+ REQUIRE(contactsDb.get().address.removeById(3));
+ REQUIRE(contactsDb.get().address.removeById(4));
// Table should be empty now
- REQUIRE(contactsdb.address.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(contactsDb.get().address.count() == 0);
}
M module-db/tests/ContactsNameTable_tests.cpp => module-db/tests/ContactsNameTable_tests.cpp +28 -39
@@ 2,95 2,84 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
-#include "Database/Database.hpp"
-#include "Databases/ContactsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include <algorithm>
-
#include <cstdint>
#include <cstdio>
#include <cstring>
-#include <filesystem>
TEST_CASE("Contacts Name Table tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(contactsPath)) {
- REQUIRE(std::filesystem::remove(contactsPath));
- }
-
- ContactsDB contactsdb(contactsPath.c_str());
- REQUIRE(contactsdb.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
ContactsNameTableRow testRow1 = {
Record(DB_ID_NONE), .contactID = DB_ID_NONE, .namePrimary = "Mateusz", .nameAlternative = "Pati"};
- const auto contactsCount = contactsdb.name.count() + 1;
+ const auto contactsCount = contactsDb.get().name.count() + 1;
// clear contacts table
for (std::uint32_t id = 1; id <= contactsCount; id++) {
- REQUIRE(contactsdb.name.removeById(id));
+ REQUIRE(contactsDb.get().name.removeById(id));
}
// add 4 elements into table
- REQUIRE(contactsdb.name.add(testRow1));
- REQUIRE(contactsdb.name.add(testRow1));
- REQUIRE(contactsdb.name.add(testRow1));
- REQUIRE(contactsdb.name.add(testRow1));
+ REQUIRE(contactsDb.get().name.add(testRow1));
+ REQUIRE(contactsDb.get().name.add(testRow1));
+ REQUIRE(contactsDb.get().name.add(testRow1));
+ REQUIRE(contactsDb.get().name.add(testRow1));
// Table should have 4 elements
- REQUIRE(contactsdb.name.count() == 4);
+ REQUIRE(contactsDb.get().name.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.nameAlternative = "Pateusz";
- REQUIRE(contactsdb.name.update(testRow1));
+ REQUIRE(contactsDb.get().name.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = contactsdb.name.getById(4);
+ auto sms = contactsDb.get().name.getById(4);
REQUIRE(sms.nameAlternative == testRow1.nameAlternative);
- // Get table row using invalid ID(should return empty contactsdb.nameRow)
- auto smsFailed = contactsdb.name.getById(100);
+ // Get table row using invalid ID(should return empty contactsDb.get().nameRow)
+ auto smsFailed = contactsDb.get().name.getById(100);
REQUIRE(smsFailed.nameAlternative == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = contactsdb.name.getLimitOffset(0, 4);
+ auto retOffsetLimit = contactsDb.get().name.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(contactsdb.name.getLimitOffsetByField(0, 4, ContactNameTableFields::NamePrimary, "Mateusz").size() == 4);
+ REQUIRE(contactsDb.get().name.getLimitOffsetByField(0, 4, ContactNameTableFields::NamePrimary, "Mateusz").size() ==
+ 4);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = contactsdb.name.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = contactsDb.get().name.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = contactsdb.name.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = contactsDb.get().name.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(contactsdb.name.countByFieldId("contact_id", 0) == 4);
+ REQUIRE(contactsDb.get().name.countByFieldId("contact_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(contactsdb.name.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(contactsDb.get().name.countByFieldId("invalid_field", 0) == 0);
- REQUIRE(contactsdb.name.removeById(2));
+ REQUIRE(contactsDb.get().name.removeById(2));
// Table should have now 3 elements
- REQUIRE(contactsdb.name.count() == 3);
+ REQUIRE(contactsDb.get().name.count() == 3);
// Remove non existing element
- REQUIRE(contactsdb.name.removeById(100));
+ REQUIRE(contactsDb.get().name.removeById(100));
// Remove all elements from table
- REQUIRE(contactsdb.name.removeById(1));
- REQUIRE(contactsdb.name.removeById(3));
- REQUIRE(contactsdb.name.removeById(4));
+ REQUIRE(contactsDb.get().name.removeById(1));
+ REQUIRE(contactsDb.get().name.removeById(3));
+ REQUIRE(contactsDb.get().name.removeById(4));
// Table should be empty now
- REQUIRE(contactsdb.name.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(contactsDb.get().name.count() == 0);
}
M module-db/tests/ContactsNumberTable_tests.cpp => module-db/tests/ContactsNumberTable_tests.cpp +29 -40
@@ 2,96 2,85 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-#include <filesystem>
+#include "Helpers.hpp"
-#include "Database/Database.hpp"
-#include "Databases/ContactsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include <algorithm>
-
#include <cstdint>
#include <cstdio>
#include <cstring>
TEST_CASE("Contacts Number Table tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(contactsPath)) {
- REQUIRE(std::filesystem::remove(contactsPath));
- }
-
- ContactsDB contactsdb{contactsPath.c_str()};
- REQUIRE(contactsdb.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
ContactsNumberTableRow testRow1 = {
Record(DB_ID_NONE), .contactID = DB_ID_NONE, .numberUser = "111222333", .numbere164 = "333222111"};
- const auto contactsCount = contactsdb.number.count() + 1;
+ const auto contactsCount = contactsDb.get().number.count() + 1;
// clear contacts table
for (std::uint32_t id = 1; id <= contactsCount; id++) {
- REQUIRE(contactsdb.number.removeById(id));
+ REQUIRE(contactsDb.get().number.removeById(id));
}
// add 4 elements into table
- REQUIRE(contactsdb.number.add(testRow1));
- REQUIRE(contactsdb.number.add(testRow1));
- REQUIRE(contactsdb.number.add(testRow1));
- REQUIRE(contactsdb.number.add(testRow1));
+ REQUIRE(contactsDb.get().number.add(testRow1));
+ REQUIRE(contactsDb.get().number.add(testRow1));
+ REQUIRE(contactsDb.get().number.add(testRow1));
+ REQUIRE(contactsDb.get().number.add(testRow1));
// Table should have 4 elements
- REQUIRE(contactsdb.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.numberUser = "999888777";
- REQUIRE(contactsdb.number.update(testRow1));
+ REQUIRE(contactsDb.get().number.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = contactsdb.number.getById(4);
+ auto sms = contactsDb.get().number.getById(4);
REQUIRE(sms.numberUser == testRow1.numberUser);
- // Get table row using invalid ID(should return empty contactsdb.numberRow)
- auto smsFailed = contactsdb.number.getById(100);
+ // Get table row using invalid ID(should return empty contactsDb.get().numberRow)
+ auto smsFailed = contactsDb.get().number.getById(100);
REQUIRE(smsFailed.numberUser == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = contactsdb.number.getLimitOffset(0, 4);
+ auto retOffsetLimit = contactsDb.get().number.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(contactsdb.number.getLimitOffsetByField(0, 4, ContactNumberTableFields::NumberE164, "333222111").size() ==
- 4);
+ REQUIRE(
+ contactsDb.get().number.getLimitOffsetByField(0, 4, ContactNumberTableFields::NumberE164, "333222111").size() ==
+ 4);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = contactsdb.number.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = contactsDb.get().number.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = contactsdb.number.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = contactsDb.get().number.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(contactsdb.number.countByFieldId("contact_id", DB_ID_NONE) == 4);
+ REQUIRE(contactsDb.get().number.countByFieldId("contact_id", DB_ID_NONE) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(contactsdb.number.countByFieldId("invalid_field", DB_ID_NONE) == 0);
+ REQUIRE(contactsDb.get().number.countByFieldId("invalid_field", DB_ID_NONE) == 0);
- REQUIRE(contactsdb.number.removeById(2));
+ REQUIRE(contactsDb.get().number.removeById(2));
// Table should have now 3 elements
- REQUIRE(contactsdb.number.count() == 3);
+ REQUIRE(contactsDb.get().number.count() == 3);
// Remove non existing element
- REQUIRE(contactsdb.number.removeById(100));
+ REQUIRE(contactsDb.get().number.removeById(100));
// Remove all elements from table
- REQUIRE(contactsdb.number.removeById(1));
- REQUIRE(contactsdb.number.removeById(3));
- REQUIRE(contactsdb.number.removeById(4));
+ REQUIRE(contactsDb.get().number.removeById(1));
+ REQUIRE(contactsDb.get().number.removeById(3));
+ REQUIRE(contactsDb.get().number.removeById(4));
// Table should be empty now
- REQUIRE(contactsdb.number.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(contactsDb.get().number.count() == 0);
}
M module-db/tests/ContactsRecord_tests.cpp => module-db/tests/ContactsRecord_tests.cpp +22 -68
@@ 2,21 2,15 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "common.hpp"
+#include "Helpers.hpp"
#include <catch2/catch.hpp>
#include "Interface/ContactRecord.hpp"
-#include <filesystem>
#include <i18n/i18n.hpp>
TEST_CASE("Contact Record db tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
const char *primaryNameTest = "PrimaryNameTest";
const char *alternativeNameTest = "AlternativeNameTest";
@@ 29,7 23,7 @@ TEST_CASE("Contact Record db tests")
const char *speeddialTest = "100";
const ContactNumberType contactNumberTypeTest = ContactNumberType::PAGER;
- ContactRecordInterface contRecInterface(&contactDB);
+ ContactRecordInterface contRecInterface(&contactsDb.get());
ContactRecord recordIN;
@@ 134,8 128,6 @@ TEST_CASE("Contact Record db tests")
REQUIRE(w.speeddial == speeddialTest);
}
}
-
- Database::deinitialize();
}
TEST_CASE("Test contact name formatting")
@@ 254,14 246,9 @@ TEST_CASE("Test converting contact data to string")
TEST_CASE("Contact record numbers update")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
ContactRecord testRecord, otherRecord;
std::array<std::string, 4> numbers = {{{"600100100"}, {"600100200"}, {"600100300"}, {"600100400"}}};
@@ 288,7 275,7 @@ TEST_CASE("Contact record numbers update")
auto newRecord = records.GetByID(1);
REQUIRE(newRecord.numbers.size() == 2);
REQUIRE(records.Update(newRecord));
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
auto validatationRecord = records.GetByID(1);
REQUIRE(validatationRecord.numbers.size() == 2);
@@ 309,7 296,7 @@ TEST_CASE("Contact record numbers update")
newRecord.numbers = std::vector<ContactRecord::Number>({ContactRecord::Number(numbers[1], std::string(""))});
REQUIRE(records.Update(newRecord));
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
auto validatationRecord = records.GetByID(1);
REQUIRE(validatationRecord.numbers.size() == 1);
@@ 323,7 310,7 @@ TEST_CASE("Contact record numbers update")
newRecord.numbers = std::vector<ContactRecord::Number>(
{ContactRecord::Number(numbers[0], std::string("")), ContactRecord::Number(numbers[1], std::string(""))});
REQUIRE(records.Update(newRecord));
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
validatationRecord = records.GetByID(1);
REQUIRE(validatationRecord.numbers.size() == 2);
@@ 348,7 335,7 @@ TEST_CASE("Contact record numbers update")
REQUIRE(records.Update(newRecord));
auto validatationRecord = records.GetByID(1);
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
REQUIRE(validatationRecord.numbers.size() == 2);
REQUIRE(validatationRecord.numbers[0].number.getEntered() == numbers[1]);
REQUIRE(validatationRecord.numbers[1].number.getEntered() == numbers[0]);
@@ 362,7 349,7 @@ TEST_CASE("Contact record numbers update")
newRecord.numbers = std::vector<ContactRecord::Number>(
{ContactRecord::Number(numbers[2], std::string("")), ContactRecord::Number(numbers[1], std::string(""))});
REQUIRE(records.Update(newRecord));
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
auto validatationRecord = records.GetByID(1);
REQUIRE(validatationRecord.numbers.size() == 2);
@@ 481,7 468,7 @@ TEST_CASE("Contact record numbers update")
newRecord.numbers = std::vector<ContactRecord::Number>(
{ContactRecord::Number(numbers[2], std::string("")), ContactRecord::Number(numbers[3], std::string(""))});
REQUIRE(records.Update(newRecord));
- REQUIRE(contactDB.number.count() == 4);
+ REQUIRE(contactsDb.get().number.count() == 4);
auto validationRecord = records.GetByIdWithTemporary(1);
REQUIRE(validationRecord.ID != DB_ID_NONE);
@@ 509,15 496,10 @@ TEST_CASE("Contact record numbers update")
TEST_CASE("Contacts list merge")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
// Preparation of DB initial state
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
std::array<std::pair<std::string, std::string>, 3> rawContactsInitial = {
{{"600100100", "test1"}, {"600100200", "test2"}, {"600100300", "test3"}}};
for (auto &rawContact : rawContactsInitial) {
@@ 603,21 585,14 @@ TEST_CASE("Contacts list merge")
REQUIRE(validatationRecord.numbers[0].number.getEntered() == rawContactsOverlapping[1].first);
REQUIRE(validatationRecord.primaryName == rawContactsOverlapping[1].second);
}
-
- Database::deinitialize();
}
TEST_CASE("Contacts list merge - advanced cases")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
// Preparation of DB initial state
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
// 3 numbers in single contact
std::array<std::string, 3> numbers = {"600100100", "600100200", "600100300"};
ContactRecord record;
@@ 650,15 625,10 @@ TEST_CASE("Contacts list merge - advanced cases")
TEST_CASE("Contacts list duplicates search")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
// Preparation of DB initial state
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
std::array<std::pair<std::string, std::string>, 3> rawContactsInitial = {
{{"600100100", "test1"}, {"600100200", "test2"}, {"600100300", "test3"}}};
for (auto &rawContact : rawContactsInitial) {
@@ 698,21 668,14 @@ TEST_CASE("Contacts list duplicates search")
REQUIRE(duplicates[1].numbers[0].number.getEntered() == rawContactsToCheck[2].first);
REQUIRE(duplicates[1].primaryName == rawContactsToCheck[2].second);
-
- Database::deinitialize();
}
TEST_CASE("Check if new contact record can be recognised as a duplicate in DB")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
// Preparation of DB initial state
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
ContactRecord testContactRecord;
testContactRecord.primaryName = "PrimaryNameTest";
@@ 747,21 710,14 @@ TEST_CASE("Check if new contact record can be recognised as a duplicate in DB")
REQUIRE(records.verifyDuplicate(duplicateContactRecord) == true);
}
-
- Database::deinitialize();
}
TEST_CASE("Check if new contact record exists in DB as a temporary contact")
{
- Database::initialize();
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(contactsPath.stem());
-
- ContactsDB contactDB(contactsPath.c_str());
- REQUIRE(contactDB.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
// Preparation of DB initial state
- auto records = ContactRecordInterface(&contactDB);
+ auto records = ContactRecordInterface(&contactsDb.get());
ContactRecord testContactRecord;
testContactRecord.primaryName = "PrimaryNameTest";
@@ 790,7 746,7 @@ TEST_CASE("Check if new contact record exists in DB as a temporary contact")
temporaryContactRecord.numbers = std::vector<ContactRecord::Number>({
ContactRecord::Number("600123452", "+48600123452", ContactNumberType::HOME),
});
- temporaryContactRecord.addToGroup(ContactsDB::temporaryGroupId());
+ temporaryContactRecord.addToGroup(contactsDb.get().groups.temporaryId());
REQUIRE(records.Add(temporaryContactRecord));
@@ 803,6 759,4 @@ TEST_CASE("Check if new contact record exists in DB as a temporary contact")
REQUIRE(records.verifyTemporary(noTemporaryContactRecord) == true);
}
-
- Database::deinitialize();
}
M module-db/tests/ContactsRingtonesTable_tests.cpp => module-db/tests/ContactsRingtonesTable_tests.cpp +28 -41
@@ 2,96 2,83 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
-#include "Database/Database.hpp"
-#include "Databases/ContactsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include <algorithm>
-#include <filesystem>
-
-#include <cstdint>
-#include <cstdio>
#include <cstring>
TEST_CASE("Contacts Ringtones Table tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(contactsPath)) {
- REQUIRE(std::filesystem::remove(contactsPath));
- }
-
- ContactsDB contactsdb{contactsPath.c_str()};
- REQUIRE(contactsdb.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
ContactsRingtonesTableRow testRow1(DB_ID_NONE, DB_ID_NONE, "/test/assets/path/ringtone.wr");
- const auto contactsCount = contactsdb.ringtones.count() + 1;
+ const auto contactsCount = contactsDb.get().ringtones.count() + 1;
// clear contacts table
for (std::uint32_t id = 1; id <= contactsCount; id++) {
- REQUIRE(contactsdb.ringtones.removeById(id));
+ REQUIRE(contactsDb.get().ringtones.removeById(id));
}
// add 4 elements into table
- REQUIRE(contactsdb.ringtones.add(testRow1));
- REQUIRE(contactsdb.ringtones.add(testRow1));
- REQUIRE(contactsdb.ringtones.add(testRow1));
- REQUIRE(contactsdb.ringtones.add(testRow1));
+ REQUIRE(contactsDb.get().ringtones.add(testRow1));
+ REQUIRE(contactsDb.get().ringtones.add(testRow1));
+ REQUIRE(contactsDb.get().ringtones.add(testRow1));
+ REQUIRE(contactsDb.get().ringtones.add(testRow1));
// Table should have 4 elements
- REQUIRE(contactsdb.ringtones.count() == 4);
+ REQUIRE(contactsDb.get().ringtones.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.assetPath = "/testnew/assets/path/ringtone2.wr";
- REQUIRE(contactsdb.ringtones.update(testRow1));
+ REQUIRE(contactsDb.get().ringtones.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = contactsdb.ringtones.getById(4);
+ auto sms = contactsDb.get().ringtones.getById(4);
REQUIRE(sms.assetPath == testRow1.assetPath);
- // Get table row using invalid ID(should return empty contactsdb.ringtonesRow)
- auto smsFailed = contactsdb.ringtones.getById(100);
+ // Get table row using invalid ID(should return empty contactsDb.get().ringtonesRow)
+ auto smsFailed = contactsDb.get().ringtones.getById(100);
REQUIRE(smsFailed.assetPath == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = contactsdb.ringtones.getLimitOffset(0, 4);
+ auto retOffsetLimit = contactsDb.get().ringtones.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(contactsdb.ringtones
+ REQUIRE(contactsDb.get()
+ .ringtones
.getLimitOffsetByField(0, 4, ContactRingtonesTableFields::AssetPath, "/test/assets/path/ringtone.wr")
.size() == 3);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = contactsdb.ringtones.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = contactsDb.get().ringtones.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = contactsdb.ringtones.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = contactsDb.get().ringtones.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(contactsdb.ringtones.countByFieldId("contact_id", 0) == 4);
+ REQUIRE(contactsDb.get().ringtones.countByFieldId("contact_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(contactsdb.ringtones.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(contactsDb.get().ringtones.countByFieldId("invalid_field", 0) == 0);
- REQUIRE(contactsdb.ringtones.removeById(2));
+ REQUIRE(contactsDb.get().ringtones.removeById(2));
// Table should have now 3 elements
- REQUIRE(contactsdb.ringtones.count() == 3);
+ REQUIRE(contactsDb.get().ringtones.count() == 3);
// Remove non existing element
- REQUIRE(contactsdb.ringtones.removeById(100));
+ REQUIRE(contactsDb.get().ringtones.removeById(100));
// Remove all elements from table
- REQUIRE(contactsdb.ringtones.removeById(1));
- REQUIRE(contactsdb.ringtones.removeById(3));
- REQUIRE(contactsdb.ringtones.removeById(4));
+ REQUIRE(contactsDb.get().ringtones.removeById(1));
+ REQUIRE(contactsDb.get().ringtones.removeById(3));
+ REQUIRE(contactsDb.get().ringtones.removeById(4));
// Table should be empty now
- REQUIRE(contactsdb.ringtones.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(contactsDb.get().ringtones.count() == 0);
}
M module-db/tests/ContactsTable_tests.cpp => module-db/tests/ContactsTable_tests.cpp +46 -51
@@ 2,22 2,15 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include <filesystem>
-#include "Databases/ContactsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include "Tables/ContactsTable.hpp"
TEST_CASE("Contacts Table tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- if (std::filesystem::exists(contactsPath)) {
- REQUIRE(std::filesystem::remove(contactsPath));
- }
-
- ContactsDB contactsdb{contactsPath.c_str()};
- REQUIRE(contactsdb.isInitialized());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
ContactsTableRow testRow1 = {Record(DB_ID_NONE),
.nameID = DB_ID_NONE,
@@ 27,93 20,95 @@ TEST_CASE("Contacts Table tests")
.speedDial = "666"
};
- REQUIRE(contactsdb.execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
- "VALUES (1,1,'Alek','Wyczesany');"));
- REQUIRE(contactsdb.execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
- "VALUES (2,2,'Zofia','Wyczesany');"));
- REQUIRE(contactsdb.execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
- "VALUES (3,3,'Cezary','Wyczesany');"));
- REQUIRE(contactsdb.execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
- "VALUES (4,4,'Alek','Arbuz');"));
REQUIRE(
- contactsdb.execute("INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (1,1,1);"));
+ contactsDb.get().execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
+ "VALUES (1,1,'Alek','Wyczesany');"));
REQUIRE(
- contactsdb.execute("INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (2,2,2);"));
+ contactsDb.get().execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
+ "VALUES (2,2,'Zofia','Wyczesany');"));
REQUIRE(
- contactsdb.execute("INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (3,1,3);"));
+ contactsDb.get().execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
+ "VALUES (3,3,'Cezary','Wyczesany');"));
REQUIRE(
- contactsdb.execute("INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (4,1,4);"));
-
- const auto contactsCount = contactsdb.contacts.count() + 1;
+ contactsDb.get().execute("INSERT OR REPLACE INTO contact_name (_id,contact_id,name_primary,name_alternative) "
+ "VALUES (4,4,'Alek','Arbuz');"));
+ REQUIRE(contactsDb.get().execute(
+ "INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (1,1,1);"));
+ REQUIRE(contactsDb.get().execute(
+ "INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (2,2,2);"));
+ REQUIRE(contactsDb.get().execute(
+ "INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (3,1,3);"));
+ REQUIRE(contactsDb.get().execute(
+ "INSERT OR REPLACE INTO contact_match_groups (_id,group_id,contact_id) VALUES (4,1,4);"));
+
+ const auto contactsCount = contactsDb.get().contacts.count() + 1;
// clear contacts table
for (std::uint32_t id = 1; id <= contactsCount; id++) {
- REQUIRE(contactsdb.contacts.removeById(id));
+ REQUIRE(contactsDb.get().contacts.removeById(id));
}
// add 4 elements into table
- REQUIRE(contactsdb.contacts.add(testRow1));
- REQUIRE(contactsdb.contacts.add(testRow1));
- REQUIRE(contactsdb.contacts.add(testRow1));
- REQUIRE(contactsdb.contacts.add(testRow1));
+ REQUIRE(contactsDb.get().contacts.add(testRow1));
+ REQUIRE(contactsDb.get().contacts.add(testRow1));
+ REQUIRE(contactsDb.get().contacts.add(testRow1));
+ REQUIRE(contactsDb.get().contacts.add(testRow1));
// Table should have 4 elements
- REQUIRE(contactsdb.contacts.count() == 4);
+ REQUIRE(contactsDb.get().contacts.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.speedDial = "777";
- REQUIRE(contactsdb.contacts.update(testRow1));
+ REQUIRE(contactsDb.get().contacts.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = contactsdb.contacts.getById(4);
+ auto sms = contactsDb.get().contacts.getById(4);
REQUIRE(sms.speedDial == testRow1.speedDial);
- // Get table row using invalid ID(should return empty contactsdb.contactsRow)
- auto smsFailed = contactsdb.contacts.getById(100);
+ // Get table row using invalid ID(should return empty contactsDb.get().contactsRow)
+ auto smsFailed = contactsDb.get().contacts.getById(100);
REQUIRE(smsFailed.speedDial == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = contactsdb.contacts.getLimitOffset(0, 4);
+ auto retOffsetLimit = contactsDb.get().contacts.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(contactsdb.contacts.getLimitOffsetByField(0, 4, ContactTableFields::SpeedDial, "666").size() == 3);
+ REQUIRE(contactsDb.get().contacts.getLimitOffsetByField(0, 4, ContactTableFields::SpeedDial, "666").size() == 3);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = contactsdb.contacts.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = contactsDb.get().contacts.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
auto sortedRetOffsetLimitBigger =
- contactsdb.contacts.GetIDsSortedByField(ContactsTable::MatchType::Name, "", 1, 4, 0);
+ contactsDb.get().contacts.GetIDsSortedByField(ContactsTable::MatchType::Name, "", 1, 4, 0);
REQUIRE(sortedRetOffsetLimitBigger.size() == 4);
- sortedRetOffsetLimitBigger = contactsdb.contacts.GetIDsSortedByName(1, 4);
+ sortedRetOffsetLimitBigger = contactsDb.get().contacts.GetIDsSortedByName(1, 4);
REQUIRE(sortedRetOffsetLimitBigger.size() == 1);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = contactsdb.contacts.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = contactsDb.get().contacts.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(contactsdb.contacts.countByFieldId("ring_id", 0) == 4);
+ REQUIRE(contactsDb.get().contacts.countByFieldId("ring_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(contactsdb.contacts.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(contactsDb.get().contacts.countByFieldId("invalid_field", 0) == 0);
- REQUIRE(contactsdb.contacts.removeById(2));
+ REQUIRE(contactsDb.get().contacts.removeById(2));
// Table should have now 3 elements
- REQUIRE(contactsdb.contacts.count() == 3);
+ REQUIRE(contactsDb.get().contacts.count() == 3);
// Remove non existing element
- REQUIRE(contactsdb.contacts.removeById(100));
+ REQUIRE(contactsDb.get().contacts.removeById(100));
// Remove all elements from table
- REQUIRE(contactsdb.contacts.removeById(1));
- REQUIRE(contactsdb.contacts.removeById(3));
- REQUIRE(contactsdb.contacts.removeById(4));
+ REQUIRE(contactsDb.get().contacts.removeById(1));
+ REQUIRE(contactsDb.get().contacts.removeById(3));
+ REQUIRE(contactsDb.get().contacts.removeById(4));
// Table should be empty now
- REQUIRE(contactsdb.contacts.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(contactsDb.get().contacts.count() == 0);
}
D module-db/tests/DbInitializer.cpp => module-db/tests/DbInitializer.cpp +0 -130
@@ 1,130 0,0 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "module-db/Database/DatabaseInitializer.hpp"
-
-#include <log/log.hpp>
-#include <Utils.hpp>
-
-#include <algorithm>
-#include <set>
-#include <array>
-
-DatabaseInitializer::DatabaseInitializer(Database *db) : db(db)
-{}
-
-bool DatabaseInitializer::run(std::filesystem::path path, std::string ext)
-{
- // Database name is database file path, need to strip off all filesystem related stuff(path, extension)
- std::filesystem::path dbpath = db->getName();
- std::string dbname = dbpath.filename().replace_extension();
-
- auto files = listFiles(path, dbname, ext);
- for (auto file : files) {
- LOG_DEBUG("Running db script: %s", file.c_str());
- auto commands = readCommands(file);
- if (!executeOnDb(commands)) {
- LOG_ERROR("Can't initialize database [%s] with [%s]", db->getName().c_str(), file.c_str());
- return false;
- }
- }
- return true;
-}
-
-std::string DatabaseInitializer::readContent(const char *filename) const noexcept
-{
- std::unique_ptr<char[]> fcontent;
- long fsize = 0;
-
- auto fp = std::fopen(filename, "r");
- if (fp) {
- std::fseek(fp, 0, SEEK_END);
- fsize = std::ftell(fp);
- std::rewind(fp);
-
- fcontent = std::make_unique<char[]>(fsize + 1);
-
- std::fread(fcontent.get(), 1, fsize, fp);
-
- std::fclose(fp);
- }
-
- return std::string(fcontent.get());
-}
-
-std::vector<std::string> DatabaseInitializer::readCommands(std::filesystem::path filePath)
-{
- auto fileContent = readContent(filePath.c_str());
- std::string currentStatement{};
- std::vector<std::string> statements{};
-
- std::string line{};
- for (auto &c : fileContent) {
- if (c != '\n') {
- line += c;
- }
- else {
- if (line.empty() || utils::startsWith(line, "--")) {
- line.clear();
- continue;
- }
- if (utils::endsWith(line, ";")) {
- statements.push_back(currentStatement + line);
- currentStatement.clear();
- line.clear();
- continue;
- }
- currentStatement += line;
-
- line.clear();
- }
- }
- return statements;
-}
-
-std::array<std::string, 3> DatabaseInitializer::splitFilename(std::string filename)
-{
- auto name = filename.substr(0, filename.find("."));
- auto prefix = name.substr(0, name.find_last_of("_"));
- auto postfix = name.substr(name.find_last_of("_") + 1, std::string::npos);
-
- return {name, prefix, postfix};
-}
-
-std::vector<std::filesystem::path> DatabaseInitializer::listFiles(std::filesystem::path path,
- std::string prefix,
- std::string ext)
-{
- std::set<std::pair<int, std::filesystem::path>> orderedFiles;
- for (const auto &entry : std::filesystem::directory_iterator(path)) {
- if (!entry.is_directory() && entry.path().has_filename()) {
- try {
- auto parts = splitFilename(entry.path().filename().string());
- auto filePrefix = parts[1];
- if (filePrefix == prefix) {
- auto num = std::stoi(parts[2]);
- if ((num == 1) || (num == 2 && (prefix == "contacts" || prefix == "notifications"))) {
- orderedFiles.insert({num, entry.path()});
- }
- }
- }
- catch (std::invalid_argument &e) {
- LOG_INFO("Ignoring file: %s", entry.path().c_str());
- }
- }
- }
-
- std::vector<std::filesystem::path> files;
- std::for_each(orderedFiles.begin(), orderedFiles.end(), [&](auto item) { files.push_back(item.second); });
- return files;
-}
-
-bool DatabaseInitializer::executeOnDb(const std::vector<std::string> statements)
-{
- for (auto st : statements) {
- if (!db->execute(st.c_str())) {
- return false;
- }
- }
- return true;
-}
A module-db/tests/Helpers.cpp => module-db/tests/Helpers.cpp +150 -0
@@ 0,0 1,150 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "Helpers.hpp"
+
+#include <Utils.hpp>
+#include <set>
+#include <algorithm>
+#include <utility>
+
+namespace
+{
+ std::string readContent(const std::string &filename) noexcept
+ {
+ auto getFileSize = [](FILE *fd) -> std::size_t {
+ std::fseek(fd, 0, SEEK_END);
+ const auto size = std::ftell(fd);
+ std::rewind(fd);
+ return size;
+ };
+
+ std::vector<char> fileContent;
+ if (const auto fp = std::fopen(filename.c_str(), "r")) {
+ const auto fileSize = getFileSize(fp);
+
+ fileContent.reserve(fileSize + 1);
+ std::fread(fileContent.data(), 1, fileSize, fp);
+ std::fclose(fp);
+ fileContent[fileSize] = '\0';
+ return fileContent.data();
+ }
+ return {};
+ }
+
+ std::vector<std::string> readCommands(const std::filesystem::path &filePath)
+ {
+ const auto fileContent = readContent(filePath.c_str());
+ std::string currentStatement{};
+ std::vector<std::string> statements{};
+
+ std::string line{};
+ for (const auto &c : fileContent) {
+ if (c != '\n') {
+ line += c;
+ }
+ else {
+ if (line.empty() || utils::startsWith(line, "--")) {
+ line.clear();
+ continue;
+ }
+ if (utils::endsWith(line, ";")) {
+ statements.push_back(currentStatement + line);
+ currentStatement.clear();
+ line.clear();
+ continue;
+ }
+ currentStatement += line;
+
+ line.clear();
+ }
+ }
+ return statements;
+ }
+
+ std::array<std::string, 3> splitFilename(const std::string &filename)
+ {
+ const auto name = filename.substr(0, filename.find("."));
+ const auto prefix = name.substr(0, name.find_last_of("_"));
+ const auto postfix = name.substr(name.find_last_of("_") + 1, std::string::npos);
+
+ return {name, prefix, postfix};
+ }
+
+ bool isOnExcludedList(const std::string &name, const std::vector<std::string> &excludedList)
+ {
+ return std::any_of(excludedList.begin(), excludedList.end(), [&name](const auto &entry) {
+ return name.find(entry) != std::string::npos;
+ });
+ }
+
+ std::vector<std::filesystem::path> listFiles(const std::filesystem::path &path,
+ const std::string &prefix,
+ const std::vector<std::string> &excludedList)
+ {
+ std::set<std::pair<int, std::filesystem::path>> orderedFiles;
+ for (const auto &entry : std::filesystem::directory_iterator(path)) {
+ if (!entry.is_directory() && entry.path().has_filename()) {
+ try {
+ const auto parts = splitFilename(entry.path().filename().string());
+ const auto &filePrefix = parts[1];
+ if (filePrefix == prefix and not isOnExcludedList(parts[0], excludedList)) {
+ orderedFiles.insert({std::stoi(parts[2]), entry.path()});
+ }
+ }
+ catch (std::invalid_argument &e) {
+ printf("Ignoring file: %s", entry.path().c_str());
+ }
+ }
+ }
+
+ std::vector<std::filesystem::path> files;
+ std::for_each(orderedFiles.begin(), orderedFiles.end(), [&](auto item) { files.push_back(item.second); });
+ return files;
+ }
+
+ bool executeOnDb(Database &db, const std::vector<std::string> &statements)
+ {
+ return std::all_of(statements.begin(), statements.end(), [&db](const auto &statement) {
+ return db.execute(statement.c_str());
+ });
+ }
+} // namespace
+
+namespace db::tests
+{
+ std::filesystem::path currentFileLocation()
+ {
+ const std::string path = __FILE__;
+ return std::filesystem::path{path.substr(0, path.rfind('/'))};
+ }
+
+ std::filesystem::path getScriptsPath()
+ {
+ return currentFileLocation() / "../databases/scripts";
+ }
+
+ /// TODO:
+ /// This function is obviously wrong and should not exist in the first place. Unfortunately, due to the
+ /// current directory structure, product specific modules and some unit tests are placed in common directories.
+ /// After proper module-db and service-db split it wont' be needed as every product-specific db unit test will be
+ /// placed in the correct directory.
+ std::filesystem::path getPurePhoneScriptsPath()
+ {
+ return currentFileLocation() / "../../products/PurePhone/services/db/databases/scripts";
+ }
+
+ bool DatabaseScripts::operator()(Database &db)
+ {
+ const std::filesystem::path dbpath = db.getName();
+ const std::string dbname = dbpath.filename().replace_extension();
+
+ const auto scripts = listFiles(directory, dbname, exclude);
+ return std::all_of(scripts.begin(), scripts.end(), [&db](const auto &script) {
+ return executeOnDb(db, readCommands(script));
+ });
+ }
+ DatabaseScripts::DatabaseScripts(std::filesystem::path directory, std::vector<std::string> &&exclude)
+ : directory{std::move(directory)}, extension{".sql"}, exclude{std::move(exclude)}
+ {}
+} // namespace db::tests<
\ No newline at end of file
A module-db/tests/Helpers.hpp => module-db/tests/Helpers.hpp +78 -0
@@ 0,0 1,78 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <Database/Database.hpp>
+#include <string>
+#include <filesystem>
+
+namespace db::tests
+{
+ std::filesystem::path getScriptsPath();
+ std::filesystem::path getPurePhoneScriptsPath();
+
+ class DatabaseScripts
+ {
+ public:
+ DatabaseScripts(std::filesystem::path directory, std::vector<std::string> &&exclude);
+ bool operator()(Database &db);
+
+ private:
+ std::filesystem::path directory;
+ std::string extension;
+ std::vector<std::string> exclude;
+ };
+
+ template <typename Db>
+ class DatabaseUnderTest
+ {
+ public:
+ DatabaseUnderTest(std::filesystem::path directory,
+ std::filesystem::path scriptsPath,
+ bool withDevelopment = false)
+ {
+ Database::initialize();
+
+ std::filesystem::remove(directory);
+
+ std::vector<std::string> excludeList;
+ if (not withDevelopment) {
+ excludeList.emplace_back("-devel");
+ }
+
+ /// Some databases initialize internal fields in the constructors. To avoid fetching wrong data from
+ /// uninitialized database fields spawn temporary database, execute any available scripts and finally
+ /// recreate it. This way we are sure database will load correct data.
+ {
+ auto tempDb = std::make_unique<Db>(directory.c_str());
+
+ if (not tempDb->isInitialized()) {
+ throw std::runtime_error("Could not initialize database");
+ }
+
+ if (not scriptsPath.empty() and not DatabaseScripts{scriptsPath, std::move(excludeList)}(*tempDb)) {
+ throw std::runtime_error("Failed to execute database scripts");
+ }
+ }
+
+ db = std::make_unique<Db>(directory.c_str());
+ }
+
+ explicit DatabaseUnderTest(std::filesystem::path directory) : DatabaseUnderTest(directory, {})
+ {}
+
+ ~DatabaseUnderTest()
+ {
+ Database::deinitialize();
+ }
+
+ Db &get()
+ {
+ return *db;
+ }
+
+ private:
+ std::unique_ptr<Db> db;
+ };
+} // namespace db::tests
M module-db/tests/MultimediaFilesTable_tests.cpp => module-db/tests/MultimediaFilesTable_tests.cpp +3 -5
@@ 3,8 3,8 @@
#include <catch2/catch.hpp>
-#include "common.hpp"
-#include <Databases/MultimediaFilesDB.hpp>
+#include <Helpers.hpp>
+#include <databases/MultimediaFilesDB.hpp>
#include <Interface/MultimediaFilesRecord.hpp>
#include <queries/multimedia_files/QueryMultimediaFilesAdd.hpp>
#include <queries/multimedia_files/QueryMultimediaFilesEdit.hpp>
@@ 79,7 79,7 @@ const std::vector<TableRow> records = {
TEST_CASE("Multimedia DB tests")
{
- DatabaseUnderTest<MultimediaFilesDB> db{"multimedia.db"};
+ db::tests::DatabaseUnderTest<MultimediaFilesDB> db{"multimedia.db", db::tests::getScriptsPath()};
MultimediaFilesRecordInterface multimediaFilesRecordInterface(&db.get());
constexpr auto PageSize = 8;
@@ 666,6 666,4 @@ TEST_CASE("Multimedia DB tests")
}
}
}
-
- REQUIRE(Database::deinitialize());
}
M module-db/tests/NotesRecord_tests.cpp => module-db/tests/NotesRecord_tests.cpp +4 -11
@@ 2,8 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-
-#include <filesystem>
+#include "Helpers.hpp"
#include <Interface/NotesRecord.hpp>
#include <queries/notes/QueryNotesGet.hpp>
#include <queries/notes/QueryNotesGetByText.hpp>
@@ 11,17 10,13 @@
#include <queries/notes/QueryNoteStore.hpp>
#include "Database/Database.hpp"
-#include "Databases/NotesDB.hpp"
+#include "module-db/databases/NotesDB.hpp"
TEST_CASE("Notes Record tests")
{
- Database::initialize();
-
- const auto notesDbPath = std::filesystem::path{"sys/user"} / "notes.db";
- NotesDB notesDb{notesDbPath.c_str()};
- REQUIRE(notesDb.isInitialized());
+ db::tests::DatabaseUnderTest<NotesDB> notesDb{"notes.db", db::tests::getPurePhoneScriptsPath()};
- NotesRecordInterface notesRecordInterface{¬esDb};
+ NotesRecordInterface notesRecordInterface{¬esDb.get()};
notesRecordInterface.RemoveAll(); // Empty the notes database.
constexpr auto testSnippet = "TEST SNIPPET";
@@ 94,6 89,4 @@ TEST_CASE("Notes Record tests")
REQUIRE(removeResult->succeed());
REQUIRE(notesRecordInterface.GetCount() == 0);
}
-
- Database::deinitialize();
};
M module-db/tests/NotesTable_tests.cpp => module-db/tests/NotesTable_tests.cpp +4 -10
@@ 2,21 2,17 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include <filesystem>
#include <Tables/NotesTable.hpp>
-#include "Database/Database.hpp"
-#include "Databases/NotesDB.hpp"
+#include "module-db/databases/NotesDB.hpp"
TEST_CASE("Notes Table tests")
{
- Database::initialize();
+ db::tests::DatabaseUnderTest<NotesDB> notesDb{"notes.db", db::tests::getPurePhoneScriptsPath()};
- const auto notesDbPath = std::filesystem::path{"sys/user"} / "notes.db";
- NotesDB notesDb{notesDbPath.c_str()};
- REQUIRE(notesDb.isInitialized());
-
- NotesTable table{¬esDb};
+ NotesTable table{¬esDb.get()};
table.removeAll();
REQUIRE(table.count() == 0);
@@ 70,6 66,4 @@ TEST_CASE("Notes Table tests")
table.removeById(1);
REQUIRE(table.count() == 0);
}
-
- Database::deinitialize();
}
M module-db/tests/NotificationsRecord_tests.cpp => module-db/tests/NotificationsRecord_tests.cpp +12 -24
@@ 1,22 1,19 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
#include <catch2/catch.hpp>
-
+#include "Helpers.hpp"
#include <Interface/NotificationsRecord.hpp>
#include <Interface/ContactRecord.hpp>
#include <Database/Database.hpp>
-#include <Databases/NotificationsDB.hpp>
-#include <Databases/ContactsDB.hpp>
+#include "module-db/databases/NotificationsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include <queries/notifications/QueryNotificationsGet.hpp>
#include <queries/notifications/QueryNotificationsIncrement.hpp>
#include <queries/notifications/QueryNotificationsDecrement.hpp>
#include <queries/notifications/QueryNotificationsClear.hpp>
#include <queries/notifications/QueryNotificationsGetAll.hpp>
-#include <filesystem>
-
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ 48,37 45,30 @@ TEST_CASE("Notifications Record tests")
REQUIRE_FALSE(testRec.contactRecord.has_value());
}
- Database::initialize();
- const auto notificationsPath = (std::filesystem::path{"sys/user"} / "notifications.db");
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- RemoveDbFiles(notificationsPath.stem());
- RemoveDbFiles(contactsPath.stem());
+ db::tests::DatabaseUnderTest<NotificationsDB> notificationsDb{"notifications.db",
+ db::tests::getPurePhoneScriptsPath()};
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
- NotificationsDB notificationsDb{notificationsPath.c_str()};
- ContactsDB contactsDb{contactsPath.c_str()};
- REQUIRE(notificationsDb.isInitialized());
- REQUIRE(contactsDb.isInitialized());
-
- const auto notificationsCount = notificationsDb.notifications.count() + 1;
+ const auto notificationsCount = notificationsDb.get().notifications.count() + 1;
// clear notifications table
for (std::size_t id = 1; id <= notificationsCount; id++) {
- REQUIRE(notificationsDb.notifications.removeById(id));
+ REQUIRE(notificationsDb.get().notifications.removeById(id));
}
- ContactRecordInterface contactRecordInterface(&contactsDb);
- NotificationsRecordInterface notificationsRecordInterface(¬ificationsDb, &contactRecordInterface);
+ ContactRecordInterface contactRecordInterface(&contactsDb.get());
+ NotificationsRecordInterface notificationsRecordInterface(¬ificationsDb.get(), &contactRecordInterface);
REQUIRE(contactRecordInterface.GetCount() == 0);
REQUIRE(notificationsRecordInterface.GetCount() == 0);
NotificationsTableRow callsRow{
Record(DB_ID_NONE), .key = static_cast<uint32_t>(NotificationsRecord::Key::Calls), .value = 0};
- REQUIRE(notificationsDb.notifications.add(callsRow));
+ REQUIRE(notificationsDb.get().notifications.add(callsRow));
NotificationsTableRow smsRow{
Record(DB_ID_NONE), .key = static_cast<uint32_t>(NotificationsRecord::Key::Sms), .value = 0};
- REQUIRE(notificationsDb.notifications.add(smsRow));
+ REQUIRE(notificationsDb.get().notifications.add(smsRow));
NotificationsRecord testRec;
auto numberOfNotifcations = notificationsRecordInterface.GetCount();
REQUIRE(numberOfNotifcations == 2); // calls and sms notifications
@@ 404,6 394,4 @@ TEST_CASE("Notifications Record tests")
getByKey(NotificationsRecord::Key::Sms, noNotificationExpected, contactNotExpected);
}
}
-
- Database::deinitialize();
}
M module-db/tests/NotificationsTable_tests.cpp => module-db/tests/NotificationsTable_tests.cpp +5 -10
@@ 1,11 1,11 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Database/Database.hpp"
-#include "Databases/NotificationsDB.hpp"
+#include "module-db/databases/NotificationsDB.hpp"
#include "Interface/NotificationsRecord.hpp"
#include "Tables/NotificationsTable.hpp"
@@ 17,13 17,10 @@
TEST_CASE("Notifications Table tests")
{
- Database::initialize();
- const auto notificationsPath = (std::filesystem::path{"sys/user"} / "notifications.db");
- RemoveDbFiles(notificationsPath.stem());
- NotificationsDB notificationsDb{notificationsPath.c_str()};
- REQUIRE(notificationsDb.isInitialized());
+ db::tests::DatabaseUnderTest<NotificationsDB> notificationDb{"notifications.db",
+ db::tests::getPurePhoneScriptsPath()};
- auto ¬ificationsTbl = notificationsDb.notifications;
+ auto ¬ificationsTbl = notificationDb.get().notifications;
const auto notificationsCount = notificationsTbl.count() + 1;
// clear notifications table
for (std::size_t id = 1; id <= notificationsCount; id++) {
@@ 170,6 167,4 @@ TEST_CASE("Notifications Table tests")
REQUIRE(entry.value == 8);
REQUIRE(entry.contactID == DB_ID_NONE);
}
-
- Database::deinitialize();
}
M module-db/tests/QueryInterface.cpp => module-db/tests/QueryInterface.cpp +7 -9
@@ 3,10 3,11 @@
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Common/Query.hpp"
-#include "Databases/ContactsDB.hpp"
+#include "module-db/databases/ContactsDB.hpp"
#include "Database/Database.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include "SMSRecord.hpp"
#include "ThreadRecord.hpp"
#include "queries/messages/threads/QueryThreadsSearchForList.hpp"
@@ 37,15 38,12 @@ namespace db
TEST_CASE("Query interface")
{
- Database::initialize();
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
- auto contactsDB = std::make_unique<ContactsDB>((std::filesystem::path{"sys/user"} / "contacts.db").c_str());
- auto smsDB = std::make_unique<SmsDB>((std::filesystem::path{"sys/user"} / "sms.db").c_str());
- auto smsInterface = std::make_unique<SMSRecordInterface>(smsDB.get(), contactsDB.get());
- auto threadInterface = std::make_unique<ThreadRecordInterface>(smsDB.get(), contactsDB.get());
+ auto smsInterface = std::make_unique<SMSRecordInterface>(&smsDb.get(), &contactsDb.get());
+ auto threadInterface = std::make_unique<ThreadRecordInterface>(&smsDb.get(), &contactsDb.get());
- REQUIRE(contactsDB);
- REQUIRE(smsDB);
REQUIRE(smsInterface);
SECTION("unknown query -> no results")
M module-db/tests/SMSRecord_tests.cpp => module-db/tests/SMSRecord_tests.cpp +9 -22
@@ 1,21 1,18 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
+#include "Helpers.hpp"
#include <Database/Database.hpp>
-#include <Databases/ContactsDB.hpp>
-#include <Databases/SmsDB.hpp>
+#include "module-db/databases/ContactsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include <Interface/ContactRecord.hpp>
#include <Interface/SMSRecord.hpp>
#include <Interface/ThreadRecord.hpp>
#include <country.hpp>
#include <PhoneNumber.hpp>
-
#include <catch2/catch.hpp>
-
#include <algorithm>
-#include <filesystem>
#include <cstdint>
#include <cstdio>
#include <cstring>
@@ 29,15 26,8 @@ struct test
TEST_CASE("SMS Record tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
- RemoveDbFiles(contactsPath.stem());
- RemoveDbFiles(smsPath.stem());
-
- ContactsDB contactsDB(contactsPath.c_str());
- SmsDB smsDB(smsPath.c_str());
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
const uint32_t dateTest = 123456789;
const uint32_t errorCodeTest = 555;
@@ 47,7 37,7 @@ TEST_CASE("SMS Record tests")
const char *bodyTest2 = "Test SMS Body2";
const SMSType typeTest = SMSType::DRAFT;
- SMSRecordInterface smsRecInterface(&smsDB, &contactsDB);
+ SMSRecordInterface smsRecInterface(&smsDb.get(), &contactsDb.get());
SMSRecord recordIN;
recordIN.date = dateTest;
@@ 136,7 126,7 @@ TEST_CASE("SMS Record tests")
}
// Remove sms records in order to check automatic management of threads and contact databases
- ThreadRecordInterface threadRecordInterface(&smsDB, &contactsDB);
+ ThreadRecordInterface threadRecordInterface(&smsDb.get(), &contactsDb.get());
REQUIRE(smsRecInterface.RemoveByID(1));
REQUIRE(smsRecInterface.RemoveByID(2));
@@ 145,7 135,7 @@ TEST_CASE("SMS Record tests")
// Test removing a message which belongs to non-existent thread
REQUIRE(smsRecInterface.Add(recordIN));
- REQUIRE(smsDB.threads.removeById(1)); // stealthy thread remove
+ REQUIRE(smsDb.get().threads.removeById(1)); // stealthy thread remove
REQUIRE(smsRecInterface.RemoveByID(1));
// Test handling of missmatch in sms vs. thread tables
@@ 166,7 156,7 @@ TEST_CASE("SMS Record tests")
.snippet = threadRec.snippet,
.type = threadRec.type};
threadRaw.msgCount = trueCount + 1; // break the DB
- REQUIRE(smsDB.threads.update(threadRaw));
+ REQUIRE(smsDb.get().threads.update(threadRaw));
REQUIRE(static_cast<int>(
smsRecInterface.GetLimitOffsetByField(0, 100, SMSRecordField::ThreadID, "1")->size()) == trueCount);
@@ 203,7 193,6 @@ TEST_CASE("SMS Record tests")
REQUIRE(smsRecInterface.Add(recordIN));
REQUIRE(smsRecInterface.Add(recordIN));
REQUIRE(smsRecInterface.Add(recordIN));
- Database::deinitialize();
}
SECTION("SMS Record Draft and Input test")
@@ 225,6 214,4 @@ TEST_CASE("SMS Record tests")
auto result = dynamic_cast<db::query::SMSGetForListResult *>(ret.get());
REQUIRE(result != nullptr);
}
-
- Database::deinitialize();
}
M module-db/tests/SMSTable_tests.cpp => module-db/tests/SMSTable_tests.cpp +35 -45
@@ 2,9 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Database/Database.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include <algorithm>
#include <filesystem>
@@ 13,16 14,7 @@
TEST_CASE("SMS Table tests")
{
- Database::initialize();
-
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
-
- if (std::filesystem::exists(smsPath)) {
- REQUIRE(std::filesystem::remove(smsPath));
- }
-
- SmsDB smsdb(smsPath.c_str());
- REQUIRE(smsdb.isInitialized());
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
SMSTableRow testRow1 = {Record(0),
.threadID = 0,
@@ 44,88 36,86 @@ TEST_CASE("SMS Table tests")
};
- const auto smsCount = smsdb.sms.count() + 1;
+ const auto smsCount = smsDb.get().sms.count() + 1;
// clear sms table
for (std::uint32_t id = 1; id <= smsCount; id++) {
- REQUIRE(smsdb.sms.removeById(id));
+ REQUIRE(smsDb.get().sms.removeById(id));
}
- REQUIRE(smsdb.sms.count() == 0);
+ REQUIRE(smsDb.get().sms.count() == 0);
// add 4 elements into table
- REQUIRE(smsdb.sms.add(testRow1));
- REQUIRE(smsdb.sms.add(testRow1));
- REQUIRE(smsdb.sms.add(testRow1));
- REQUIRE(smsdb.sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow1));
// Table should have 4 elements
- REQUIRE(smsdb.sms.count() == 4);
+ REQUIRE(smsDb.get().sms.count() == 4);
// update existing element in table
testRow1.ID = 4;
testRow1.body = "updated Test SMS message ";
- REQUIRE(smsdb.sms.update(testRow1));
+ REQUIRE(smsDb.get().sms.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto sms = smsdb.sms.getById(4);
+ auto sms = smsDb.get().sms.getById(4);
REQUIRE(sms.body == testRow1.body);
- // Get table row using invalid ID(should return empty smsdb.smsRow)
- auto smsFailed = smsdb.sms.getById(100);
+ // Get table row using invalid ID(should return empty smsDb.get().smsRow)
+ auto smsFailed = smsDb.get().sms.getById(100);
REQUIRE(smsFailed.body == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = smsdb.sms.getLimitOffset(0, 4);
+ auto retOffsetLimit = smsDb.get().sms.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(smsdb.sms.getLimitOffsetByField(0, 4, SMSTableFields::Date, "0").size() == 4);
+ REQUIRE(smsDb.get().sms.getLimitOffsetByField(0, 4, SMSTableFields::Date, "0").size() == 4);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = smsdb.sms.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = smsDb.get().sms.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = smsdb.sms.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = smsDb.get().sms.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get count of elements by field's ID
- REQUIRE(smsdb.sms.countByFieldId("thread_id", 0) == 4);
+ REQUIRE(smsDb.get().sms.countByFieldId("thread_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(smsdb.sms.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(smsDb.get().sms.countByFieldId("invalid_field", 0) == 0);
- REQUIRE(smsdb.sms.removeById(2));
+ REQUIRE(smsDb.get().sms.removeById(2));
// Table should have now 3 elements
- REQUIRE(smsdb.sms.count() == 3);
+ REQUIRE(smsDb.get().sms.count() == 3);
// Remove non existing element
- REQUIRE(smsdb.sms.removeById(100));
+ REQUIRE(smsDb.get().sms.removeById(100));
// Remove all elements from table
- REQUIRE(smsdb.sms.removeById(1));
- REQUIRE(smsdb.sms.removeById(3));
- REQUIRE(smsdb.sms.removeById(4));
+ REQUIRE(smsDb.get().sms.removeById(1));
+ REQUIRE(smsDb.get().sms.removeById(3));
+ REQUIRE(smsDb.get().sms.removeById(4));
// Table should be empty now
- REQUIRE(smsdb.sms.count() == 0);
+ REQUIRE(smsDb.get().sms.count() == 0);
SECTION("SMS Draft and Input Table test")
{
- REQUIRE(smsdb.sms.add(testRow1));
- REQUIRE(smsdb.sms.add(testRow1));
- REQUIRE(smsdb.sms.add(testRow2));
+ REQUIRE(smsDb.get().sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow1));
+ REQUIRE(smsDb.get().sms.add(testRow2));
- REQUIRE(smsdb.sms.countWithoutDraftsByThreadId(0) == 2);
- REQUIRE(smsdb.sms.count() == 3);
+ REQUIRE(smsDb.get().sms.countWithoutDraftsByThreadId(0) == 2);
+ REQUIRE(smsDb.get().sms.count() == 3);
- REQUIRE(smsdb.sms.getDraftByThreadId(0).body == "Test Draft SMS");
+ REQUIRE(smsDb.get().sms.getDraftByThreadId(0).body == "Test Draft SMS");
- auto results = smsdb.sms.getByThreadIdWithoutDraftWithEmptyInput(0, 0, 10);
+ auto results = smsDb.get().sms.getByThreadIdWithoutDraftWithEmptyInput(0, 0, 10);
REQUIRE(results.size() == 3);
REQUIRE(results.back().type == SMSType::INPUT);
}
-
- Database::deinitialize();
}
M module-db/tests/SMSTemplateRecord_tests.cpp => module-db/tests/SMSTemplateRecord_tests.cpp +4 -19
@@ 2,31 2,18 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
-
+#include "Helpers.hpp"
#include "Interface/SMSTemplateRecord.hpp"
-#include "Database/Database.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include <algorithm>
-#include <filesystem>
-
-#include <cstdint>
-#include <cstdio>
#include <cstring>
TEST_CASE("SMS templates Record tests")
{
- Database::initialize();
-
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
- if (std::filesystem::exists(smsPath)) {
- REQUIRE(std::filesystem::remove(smsPath));
- }
-
- SmsDB smsDB(smsPath.c_str());
- REQUIRE(smsDB.isInitialized());
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
- SMSTemplateRecordInterface SMSTemplateRecordInterface(&smsDB);
+ SMSTemplateRecordInterface SMSTemplateRecordInterface(&smsDb.get());
SMSTemplateRecord testRec;
testRec.text = "Test text";
testRec.lastUsageTimestamp = 100;
@@ 105,6 92,4 @@ TEST_CASE("SMS templates Record tests")
// Table should be empty now
REQUIRE(SMSTemplateRecordInterface.GetCount() == 0);
}
-
- Database::deinitialize();
}
M module-db/tests/SMSTemplateTable_tests.cpp => module-db/tests/SMSTemplateTable_tests.cpp +4 -13
@@ 2,9 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Database/Database.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include "Tables/SMSTemplateTable.hpp"
@@ 17,17 18,9 @@
TEST_CASE("SMS Templates Table tests")
{
- Database::initialize();
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
- if (std::filesystem::exists(smsPath)) {
- REQUIRE(std::filesystem::remove(smsPath));
- }
-
- SmsDB smsDb{smsPath.c_str()};
- REQUIRE(smsDb.isInitialized());
-
- auto &templatesTbl = smsDb.templates;
+ auto &templatesTbl = smsDb.get().templates;
SMSTemplateTableRow testRow = {Record(0), .text = "Test text", .lastUsageTimestamp = 100};
@@ 121,6 114,4 @@ TEST_CASE("SMS Templates Table tests")
// Table should be empty now
REQUIRE(templatesTbl.count() == 0);
}
-
- Database::deinitialize();
}
M module-db/tests/ThreadRecord_tests.cpp => module-db/tests/ThreadRecord_tests.cpp +8 -19
@@ 1,11 1,11 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
+#include "Helpers.hpp"
#include <Database/Database.hpp>
-#include <Databases/ContactsDB.hpp>
-#include <Databases/SmsDB.hpp>
+#include "module-db/databases/ContactsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include <Interface/ContactRecord.hpp>
#include <Interface/SMSRecord.hpp>
#include <Interface/ThreadRecord.hpp>
@@ 27,24 27,15 @@
TEST_CASE("Thread Record tests")
{
- Database::initialize();
-
- const auto contactsPath = (std::filesystem::path{"sys/user"} / "contacts.db");
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
- RemoveDbFiles(contactsPath.stem());
- RemoveDbFiles(smsPath.stem());
-
- SmsDB smsDB(smsPath.c_str());
- REQUIRE(smsDB.isInitialized());
- ContactsDB contactsDB(contactsPath.c_str());
- REQUIRE(contactsDB.isInitialized());
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
+ db::tests::DatabaseUnderTest<ContactsDB> contactsDb{"contacts.db", db::tests::getPurePhoneScriptsPath()};
const uint32_t dateTest = 123456789;
const char *snippetTest = "Test snippet";
const char *snippetTest2 = "Test snippet2";
const SMSType typeTest = SMSType::UNKNOWN;
- ThreadRecordInterface threadRecordInterface1(&smsDB, &contactsDB);
+ ThreadRecordInterface threadRecordInterface1(&smsDb.get(), &contactsDb.get());
ThreadRecord recordIN;
recordIN.date = dateTest;
@@ 187,7 178,7 @@ TEST_CASE("Thread Record tests")
const utils::PhoneNumber phoneNumber("+48600123456", utils::country::Id::UNKNOWN);
const std::string lastSmsBody = "Ola";
- SMSRecordInterface smsRecInterface(&smsDB, &contactsDB);
+ SMSRecordInterface smsRecInterface(&smsDb.get(), &contactsDb.get());
SMSRecord recordIN;
recordIN.date = 123456789;
recordIN.errorCode = 0;
@@ 242,7 233,7 @@ TEST_CASE("Thread Record tests")
const utils::PhoneNumber phoneNumber("+48600123456", utils::country::Id::UNKNOWN);
- SMSRecordInterface smsRecInterface(&smsDB, &contactsDB);
+ SMSRecordInterface smsRecInterface(&smsDb.get(), &contactsDb.get());
SMSRecord recordIN;
recordIN.date = 123456789;
recordIN.errorCode = 0;
@@ 279,6 270,4 @@ TEST_CASE("Thread Record tests")
REQUIRE(smsRec->body == smsBody);
}
}
-
- Database::deinitialize();
}
M module-db/tests/ThreadsTable_tests.cpp => module-db/tests/ThreadsTable_tests.cpp +29 -38
@@ 2,9 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include "Helpers.hpp"
#include "Database/Database.hpp"
-#include "Databases/SmsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include "Tables/ThreadsTable.hpp"
#include <algorithm>
@@ 16,15 17,7 @@
TEST_CASE("Threads Table tests")
{
- Database::initialize();
-
- const auto smsPath = (std::filesystem::path{"sys/user"} / "sms.db");
- if (std::filesystem::exists(smsPath)) {
- REQUIRE(std::filesystem::remove(smsPath));
- }
-
- SmsDB smsdb{smsPath.c_str()};
- REQUIRE(smsdb.isInitialized());
+ db::tests::DatabaseUnderTest<SmsDB> smsDb{"sms.db", db::tests::getPurePhoneScriptsPath()};
ThreadsTableRow testRow1 = {Record(0),
.date = 0,
@@ 36,74 29,72 @@ TEST_CASE("Threads Table tests")
};
- const auto smsThreadsCount = smsdb.threads.count() + 1;
+ const auto smsThreadsCount = smsDb.get().threads.count() + 1;
// clear threads table
for (std::size_t id = 1; id <= smsThreadsCount; id++) {
- REQUIRE(smsdb.threads.removeById(id));
+ REQUIRE(smsDb.get().threads.removeById(id));
}
// add 4 elements into table
- REQUIRE(smsdb.threads.add(testRow1));
- REQUIRE(smsdb.threads.add(testRow1));
- REQUIRE(smsdb.threads.add(testRow1));
+ REQUIRE(smsDb.get().threads.add(testRow1));
+ REQUIRE(smsDb.get().threads.add(testRow1));
+ REQUIRE(smsDb.get().threads.add(testRow1));
testRow1.unreadMsgCount = 10;
- REQUIRE(smsdb.threads.add(testRow1));
+ REQUIRE(smsDb.get().threads.add(testRow1));
// Table should have 4 elements
- REQUIRE(smsdb.threads.count() == 4);
- REQUIRE(smsdb.threads.count(EntryState::ALL) == 4);
- REQUIRE(smsdb.threads.count(EntryState::READ) == 3);
- REQUIRE(smsdb.threads.count(EntryState::UNREAD) == 1);
+ REQUIRE(smsDb.get().threads.count() == 4);
+ REQUIRE(smsDb.get().threads.count(EntryState::ALL) == 4);
+ REQUIRE(smsDb.get().threads.count(EntryState::READ) == 3);
+ REQUIRE(smsDb.get().threads.count(EntryState::UNREAD) == 1);
// update existing element in table
testRow1.ID = 4;
testRow1.snippet = "updated Test snippet";
- REQUIRE(smsdb.threads.update(testRow1));
+ REQUIRE(smsDb.get().threads.update(testRow1));
// Get table row using valid ID & check if it was updated
- auto thread = smsdb.threads.getById(4);
+ auto thread = smsDb.get().threads.getById(4);
REQUIRE(thread.snippet == testRow1.snippet);
// Get table row using invalid ID(should return empty SMSTableRow)
- auto threadFailed = smsdb.threads.getById(100);
+ auto threadFailed = smsDb.get().threads.getById(100);
REQUIRE(threadFailed.snippet == "");
// Get table rows using valid offset/limit parameters
- auto retOffsetLimit = smsdb.threads.getLimitOffset(0, 4);
+ auto retOffsetLimit = smsDb.get().threads.getLimitOffset(0, 4);
REQUIRE(retOffsetLimit.size() == 4);
// Get table rows using invalid limit parameters(should return 4 elements instead of 100)
- auto retOffsetLimitBigger = smsdb.threads.getLimitOffset(0, 100);
+ auto retOffsetLimitBigger = smsDb.get().threads.getLimitOffset(0, 100);
REQUIRE(retOffsetLimitBigger.size() == 4);
// Get table rows using invalid offset/limit parameters(should return empty object)
- auto retOffsetLimitFailed = smsdb.threads.getLimitOffset(5, 4);
+ auto retOffsetLimitFailed = smsDb.get().threads.getLimitOffset(5, 4);
REQUIRE(retOffsetLimitFailed.size() == 0);
// Get table rows using valid offset/limit parameters and specific field's ID
- REQUIRE(smsdb.threads.getLimitOffsetByField(0, 4, ThreadsTableFields::MsgCount, "0").size() == 4);
+ REQUIRE(smsDb.get().threads.getLimitOffsetByField(0, 4, ThreadsTableFields::MsgCount, "0").size() == 4);
// Get count of elements by field's ID
- REQUIRE(smsdb.threads.countByFieldId("contact_id", 0) == 4);
+ REQUIRE(smsDb.get().threads.countByFieldId("contact_id", 0) == 4);
// Get count of elements by invalid field's ID
- REQUIRE(smsdb.threads.countByFieldId("invalid_field", 0) == 0);
+ REQUIRE(smsDb.get().threads.countByFieldId("invalid_field", 0) == 0);
- REQUIRE(smsdb.threads.removeById(2));
+ REQUIRE(smsDb.get().threads.removeById(2));
// Table should have now 3 elements
- REQUIRE(smsdb.threads.count() == 3);
+ REQUIRE(smsDb.get().threads.count() == 3);
// Remove non existing element
- REQUIRE(smsdb.threads.removeById(100));
+ REQUIRE(smsDb.get().threads.removeById(100));
// Remove all elements from table
- REQUIRE(smsdb.threads.removeById(1));
- REQUIRE(smsdb.threads.removeById(3));
- REQUIRE(smsdb.threads.removeById(4));
+ REQUIRE(smsDb.get().threads.removeById(1));
+ REQUIRE(smsDb.get().threads.removeById(3));
+ REQUIRE(smsDb.get().threads.removeById(4));
// Table should be empty now
- REQUIRE(smsdb.threads.count() == 0);
-
- Database::deinitialize();
+ REQUIRE(smsDb.get().threads.count() == 0);
}
D module-db/tests/common.cpp => module-db/tests/common.cpp +0 -16
@@ 1,16 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "common.hpp"
-#include <vector>
-#include <filesystem>
-
-void RemoveDbFiles(const std::string &dbName)
-{
- std::vector<std::string> dbFileExt = {".db", ".db-journal", ".db-wal"};
- for (const auto &ext : dbFileExt) {
- const auto dbPath = (std::filesystem::path{"sys/user"} / std::filesystem::path{dbName + ext});
- if (std::filesystem::exists(dbPath)) {
- std::filesystem::remove(dbPath.c_str());
- }
- }
-}
D module-db/tests/common.hpp => module-db/tests/common.hpp +0 -45
@@ 1,45 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include "Database/Database.hpp"
-#include <catch2/catch.hpp>
-#include <string>
-#include <filesystem>
-
-void RemoveDbFiles(const std::string &dbName);
-
-template <typename Db>
-class DatabaseUnderTest
-{
- public:
- explicit DatabaseUnderTest(std::filesystem::path name)
- {
- Database::initialize();
-
- if (std::filesystem::exists(name)) {
- std::filesystem::remove(name);
- }
-
- db = std::make_unique<Db>(name.c_str());
-
- if (not db->isInitialized()) {
- throw std::runtime_error("Could not initialize database");
- }
- }
-
- ~DatabaseUnderTest()
- {
- Database::deinitialize();
- }
-
- Db &get()
- {
- return *db;
- }
-
- private:
- std::filesystem::path name;
- std::unique_ptr<Db> db;
-};
D module-db/tests/test-initializer/CMakeLists.txt => module-db/tests/test-initializer/CMakeLists.txt +0 -12
@@ 1,12 0,0 @@
-add_catch2_executable(
- NAME
- db-initializer
- SRCS
- "${CMAKE_CURRENT_SOURCE_DIR}/unittest.cpp"
-
- LIBS
- module-sys
- module-db
-
- USE_FS
-)
D module-db/tests/test-initializer/unittest.cpp => module-db/tests/test-initializer/unittest.cpp +0 -292
@@ 1,292 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include <catch2/catch.hpp>
-
-#include "Database/Database.hpp"
-#include "Database/DatabaseInitializer.hpp"
-
-#include "Tables/SMSTable.hpp"
-
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-
-#include <cstdint>
-#include <cstdio>
-#include <cstring>
-
-TEST_CASE("Create and destroy simple database")
-{
- Database::initialize();
-
- SECTION("Create database")
- {
-
- Database testDB("test.db");
-
- const char *media_album_table = "CREATE TABLE IF NOT EXISTS albums("
- "_id INTEGER PRIMARY KEY,"
- "artist_id INTEGER,"
- "name TEXT UNIQUE,"
- "FOREIGN KEY(artist_id) REFERENCES artists(_id)"
- ");";
-
- const char *media_artist_table = "CREATE TABLE IF NOT EXISTS artists("
- "_id INTEGER PRIMARY KEY,"
- "name TEXT UNIQUE"
- ");";
-
- const char *media_songs_table = "CREATE TABLE IF NOT EXISTS tracks("
- "_id INTEGER PRIMARY KEY,"
- "filename TEXT UNIQUE,"
- "name TEXT,"
- "duration INTEGER,"
- "artist_id INTEGER,"
- "album_id INTEGER,"
- "cover INTEGER,"
- "FOREIGN KEY(artist_id) REFERENCES artists(_id),"
- "FOREIGN KEY(album_id) REFERENCES albums(_id)"
- ");";
-
- const char *testdb_queries[] = {media_artist_table, media_album_table, media_songs_table};
-
- // execute all commands from the array
- for (uint32_t i = 0; i < sizeof(testdb_queries) / sizeof(char *); i++) {
- REQUIRE(testDB.execute(testdb_queries[i]) == true);
- }
- }
-
- SECTION("Add records to database")
- {
- Database testDB("test.db");
-
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus") == true);
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus2") == true);
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus3") == true);
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus4") == true);
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus5") == true);
- REQUIRE(testDB.execute("insert or ignore into artists ( name ) VALUES ( '%q');", "Mati Patus6") == true);
- }
-
- SECTION("query database")
- {
- Database testDB("test.db");
-
- auto queryRes = testDB.query("SELECT * from artists;");
-
- REQUIRE(queryRes->getFieldCount() == 2);
- REQUIRE(queryRes->getRowCount() == 6);
- }
-
- SECTION("Store database into backup file")
- {
- std::string backupPathDB = "testbackup.db";
- std::remove(backupPathDB.c_str());
- Database testDB("test.db");
- REQUIRE(testDB.storeIntoFile(backupPathDB) == true);
- std::ifstream f(backupPathDB);
- REQUIRE(f.good() == true);
- }
-
- Database::deinitialize();
-}
-
-class ScopedDir
-{
- public:
- explicit ScopedDir(const std::string &p) : path(p)
- {
- if (!(std::filesystem::exists(path.c_str()))) {
- REQUIRE(std::filesystem::create_directory(path.c_str()));
- }
- }
-
- ~ScopedDir()
- {
- if (std::filesystem::exists(path.c_str())) {
- REQUIRE(std::filesystem::remove_all(path.c_str()) > 0);
- }
- }
-
- auto operator()(const std::string &file = "") -> std::filesystem::path
- {
- return path / file;
- }
-
- private:
- std::filesystem::path path;
-};
-
-TEST_CASE("Database initialization scripts")
-{
- Database::initialize();
-
- const std::string script_create = "CREATE TABLE IF NOT EXISTS tracks("
- "_id INTEGER PRIMARY KEY,"
- "filename TEXT UNIQUE,"
- "name TEXT,"
- "duration INTEGER,"
- "artist_id INTEGER,"
- "album_id INTEGER,"
- "cover INTEGER,"
- "FOREIGN KEY(artist_id) REFERENCES artists(_id),"
- "FOREIGN KEY(album_id) REFERENCES albums(_id)"
- ");\n";
-
- const std::string script_insert = "insert or ignore into tracks(name) VALUES('ala ma kota');\n";
-
- const std::string script_comment = "--insert or ignore into tracks(name) VALUES('ula');\n"
- "insert or ignore into tracks(name) VALUES('ala ma kota');\n"
- "--insert or ignore into tracks(name) VALUES('basia');\n"
- "insert or ignore into tracks(name) VALUES('ala ma kota');\n";
-
- const std::string script_invalid = "inserts error(name) VALUES('super');\n";
-
- SECTION("list files")
- {
- ScopedDir dir("scripts");
-
- auto file = std::fopen(dir("test_1.sql").c_str(), "w");
- std::fclose(file);
-
- file = std::fopen(dir("test_021.sql").c_str(), "w");
- std::fclose(file);
-
- file = std::fopen(dir("test_011.sql").c_str(), "w");
- std::fclose(file);
-
- file = std::fopen(dir("test_013.sql").c_str(), "w");
- std::fclose(file);
-
- file = std::fopen(dir("noprefix_003.sql").c_str(), "w");
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto files = initializer.listFiles("scripts", "test", "sql");
-
- REQUIRE(files.size() == 4);
- REQUIRE(files[0] == (std::filesystem::path{"scripts"} / "test_1.sql"));
- REQUIRE(files[1] == (std::filesystem::path{"scripts"} / "test_011.sql"));
- REQUIRE(files[2] == (std::filesystem::path{"scripts"} / "test_013.sql"));
- REQUIRE(files[3] == (std::filesystem::path{"scripts"} / "test_021.sql"));
- }
-
- SECTION("execute single valid script")
- {
- ScopedDir dir("execute_valid_script");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fwrite(script_create.data(), sizeof(char), script_create.size(), file);
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.size() == 1);
-
- bool r = initializer.run(dir());
- REQUIRE(r == true);
- }
-
- SECTION("execute 2 valid script files")
- {
- ScopedDir dir("scripts");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fwrite(script_create.data(), sizeof(char), script_create.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.size() == 2);
-
- bool result = initializer.run(dir());
- REQUIRE(result == true);
- }
-
- SECTION("execute multiple valid script files")
- {
- ScopedDir dir("scripts");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fwrite(script_create.data(), sizeof(char), script_create.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fwrite(script_insert.data(), sizeof(char), script_insert.size(), file);
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.size() == 6);
-
- bool result = initializer.run(dir());
- REQUIRE(result == true);
- }
-
- SECTION("execute empty script files")
- {
- ScopedDir dir("scripts");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.empty());
-
- bool result = initializer.run(dir());
- REQUIRE(result == true);
- }
-
- SECTION("execute script file with comment")
- {
- ScopedDir dir("read_script_file_with_comment");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fwrite(script_create.data(), sizeof(char), script_create.size(), file);
- std::fwrite(script_comment.data(), sizeof(char), script_comment.size(), file);
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.size() == 3);
-
- bool result = initializer.run(dir());
- REQUIRE(result == true);
- }
-
- SECTION("execute invalid script")
- {
- ScopedDir dir("execute_invalid_script");
- std::string test_file("test_001.sql");
-
- auto file = std::fopen(dir(test_file).c_str(), "w");
- std::fwrite(script_create.data(), sizeof(char), script_create.size(), file);
- std::fwrite(script_invalid.data(), sizeof(char), script_invalid.size(), file);
- std::fclose(file);
-
- Database db(dir("test.db").c_str());
- DatabaseInitializer initializer(&db);
- auto commands = initializer.readCommands(dir(test_file));
- REQUIRE(commands.size() == 2);
-
- bool result = initializer.run(dir());
- REQUIRE(result == false);
- }
-
- REQUIRE(Database::deinitialize() == true);
-}
M module-services/service-db/DBServiceAPI.cpp => module-services/service-db/DBServiceAPI.cpp +0 -1
@@ 16,7 16,6 @@
#include <SMSTemplateRecord.hpp>
#include <system/Common.hpp>
#include <Service/Service.hpp>
-#include <Tables/CountryCodesTable.hpp>
#include <ThreadRecord.hpp>
#include <Utils.hpp>
#include <log/log.hpp>
M module-services/service-db/agents/settings/SettingsAgent.cpp => module-services/service-db/agents/settings/SettingsAgent.cpp +1 -1
@@ 70,7 70,7 @@ void SettingsAgent::unRegisterMessages()
auto SettingsAgent::getDbFilePath() -> const std::string
{
- return (purefs::dir::getUserDiskPath() / dbName).string();
+ return (purefs::dir::getDatabasesPath() / dbName).string();
}
auto SettingsAgent::getAgentName() -> const std::string
{
M module-services/service-db/test/CMakeLists.txt => module-services/service-db/test/CMakeLists.txt +1 -2
@@ 8,7 8,7 @@ add_catch2_executable(
test-service-db-quotes.cpp
test-factory-settings.cpp
LIBS
- iosyscalls
+ module-db::test::helpers
module-audio
module-cellular
module-sys
@@ 16,7 16,6 @@ add_catch2_executable(
module-vfs
service-audio
service-cellular
- USE_FS
)
add_catch2_executable(
A module-services/service-db/test/lang/English.json => module-services/service-db/test/lang/English.json +733 -0
@@ 0,0 1,733 @@
+{
+ "metadata": {
+ "display_name": "English"
+ },
+ "common_add": "ADD",
+ "common_open": "OPEN",
+ "common_call": "CALL",
+ "common_save": "SAVE",
+ "common_edit": "EDIT",
+ "common_import": "IMPORT",
+ "common_send": "SEND",
+ "common_reply": "REPLY",
+ "common_confirm": "CONFIRM",
+ "common_select": "SELECT",
+ "common_use": "USE",
+ "common_ok": "OK",
+ "common_back": "BACK",
+ "common_skip": "SKIP",
+ "common_contacts": "CONTACTS",
+ "common_set": "SET",
+ "common_show": "SHOW",
+ "common_yes": "Yes",
+ "common_no": "No",
+ "common_switch": "SWITCH",
+ "common_options": "OPTIONS",
+ "common_options_title": "Options",
+ "common_information": "Information",
+ "common_check": "CHECK",
+ "common_uncheck": "UNCHECK",
+ "common_emoji": "EMOJI",
+ "common_special_characters": "SPECIAL",
+ "common_start": "START",
+ "common_stop": "STOP",
+ "common_resume": "RESUME",
+ "common_pause": "PAUSE",
+ "common_play": "PLAY",
+ "common_retry": "TRY AGAIN",
+ "common_replace": "REPLACE",
+ "common_abort": "ABORT",
+ "common_connect": "CONNECT",
+ "common_disconnect": "DISCONNECT",
+ "common_forget": "FORGET",
+ "common_adjust": "ADJUST",
+ "common_mo": "MO",
+ "common_tu": "TU",
+ "common_we": "WE",
+ "common_th": "TH",
+ "common_fr": "FR",
+ "common_sa": "SA",
+ "common_su": "SU",
+ "common_mon": "Mon",
+ "common_tue": "Tue",
+ "common_wed": "Wed",
+ "common_thu": "Thu",
+ "common_fri": "Fri",
+ "common_sat": "Sat",
+ "common_sun": "Sun",
+ "common_monday": "Monday",
+ "common_tuesday": "Tuesday",
+ "common_wednesday": "Wednesday",
+ "common_thursday": "Thursday",
+ "common_friday": "Friday",
+ "common_saturday": "Saturday",
+ "common_sunday": "Sunday",
+ "common_january": "January",
+ "common_february": "February",
+ "common_march": "March",
+ "common_april": "April",
+ "common_may": "May",
+ "common_june": "June",
+ "common_july": "July",
+ "common_august": "August",
+ "common_september": "September",
+ "common_october": "October",
+ "common_november": "November",
+ "common_december": "December",
+ "common_yesterday": "Yesterday",
+ "common_today": "Today",
+ "common_results_prefix": "Results: ",
+ "common_search": "SEARCH",
+ "common_accept": "ACCEPT",
+ "common_minute_lower": "minute",
+ "common_minutes_lower": "minutes",
+ "common_minutes_lower_genitive": "minutes",
+ "common_minute_short": "min",
+ "common_second_lower": "second",
+ "common_seconds_lower": "seconds",
+ "common_seconds_lower_genitive": "seconds",
+ "common_second_short": "sec",
+ "common_paused": "Paused",
+ "common_text_copy": "Copy text",
+ "common_text_paste": "Paste text",
+ "locale_12hour_min": "%I:%M %p",
+ "locale_12hour_min_short": "%I:%M",
+ "locale_24hour_min": "%H:%M",
+ "locale_date_DD_MM_YYYY": "%d.%m.%Y",
+ "locale_date_MM_DD_YYYY": "%m.%d.%Y",
+ "locale_date_DD_MM": "%d.%m",
+ "locale_date_MM_DD": "%m.%d",
+ "locale_date_Day_DD_Mon": "%A, %d %b",
+ "locale_date_Day_Mon_DD": "%A, %b %d",
+ "common_AM": "AM",
+ "common_PM": "PM",
+ "duration_min_0sec": "%M:%0S",
+ "duration_0min_0sec": "%0M:%0S",
+ "duration_0hmin_0sec": "%0N:%0S",
+ "duration_hour_0min_0sec": "%H:%0M:%0S",
+ "brightness_text": "BRIGHTNESS",
+ "phone_needs_rebooting": "Your phone needs rebooting. Press any key to confirm and please remove the battery for 10 seconds to perform a full reboot",
+ "home_modes_connected": "CONNECTED",
+ "home_modes_notdisturb": "DO NOT DISTURB",
+ "home_modes_offline": "OFFLINE",
+ "home_modes_message_only": "Message only",
+ "statusbar_battery_charging": "Charg",
+ "statusbar_battery_plugged": "Plug",
+ "app_alarm_clock_title_main": "Alarm clock",
+ "app_alarm_clock_repeat_never": "Never",
+ "app_alarm_clock_repeat_everyday": "Everyday",
+ "app_alarm_clock_repeat_week_days": "Weekdays",
+ "app_alarm_clock_repeat_custom": "Custom",
+ "app_alarm_clock_no_alarms_information": "<text align='center' color='4'>No alarms yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_alarm_clock_options_edit": "Edit",
+ "app_alarm_clock_options_delete": "Delete",
+ "app_alarm_clock_options_turn_off_all_alarms": "Turn off all alarms",
+ "app_alarm_clock_delete_confirmation": "Delete this alarm?",
+ "app_alarm_clock_new_alarm_title": "New alarm",
+ "app_alarm_clock_edit_alarm_title": "Edit alarm",
+ "app_alarm_clock_sound": "Sound",
+ "app_alarm_clock_snooze": "Snooze",
+ "app_alarm_clock_repeat": "Repeat",
+ "app_alarm_clock_no_snooze": "None",
+ "app_alarm_clock_snooze_5_min": "5 min",
+ "app_alarm_clock_snooze_10_min": "10 min",
+ "app_alarm_clock_snooze_15_min": "15 min",
+ "app_alarm_clock_snooze_30_min": "30 min",
+ "app_alarm_clock_custom_repeat_title": "Custom repeat",
+ "app_calendar_title_main": "Calendar",
+ "app_calendar_all_day": "All day",
+ "app_calculator_title_main": "Calculator",
+ "app_calculator_equals": "EQUALS",
+ "app_calculator_decimal_separator": ".",
+ "app_calculator_error": "Error",
+ "app_options_invalid_option": " <Invalid Option> ",
+ "app_options_contact_details": "Contact details",
+ "app_options_contact_add": "Add to contacts",
+ "app_options_contact_edit": "Edit Contact",
+ "app_notes_title_main": "Notes",
+ "app_notes_edit_new_note": "Edit/New Note",
+ "app_notes_edit": "EDIT",
+ "app_notes_edited": "Edited",
+ "app_notes_delete_note": "Delete",
+ "app_notes_note_delete_confirmation": "Do you really want to delete this note?",
+ "app_notes_no_notes": "<text align='center' color='4'>No notes yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_notes_search_no_results": "No notes found.",
+ "app_calllog_title_main": "Calls",
+ "app_calllog_no_calls": "<text align='center' color='4'>No calls yet.</text>",
+ "app_calllog_type": "Call",
+ "app_calllog_duration": "Duration",
+ "app_calllog_incoming_call": "Incoming call",
+ "app_calllog_outgoing_call": "Outgoing call",
+ "app_calllog_missed_call": "Missed call",
+ "app_calllog_rejected_call": "Rejected call",
+ "app_calllog_empty_incoming": "<text color='5'>Incoming</text>",
+ "app_calllog_empty_outgoing": "<text color='5'>Outgoing</text>",
+ "app_calllog_empty_missed": "<text color='5'>Missed</text>",
+ "app_calllog_date": "Date",
+ "app_calllog_options_delete_call": "Delete call",
+ "app_calllog_delete_call_confirmation": "Delete this call from the list?",
+ "app_calllog_delete_all_calls": "Delete all calls",
+ "app_calllog_delete_all_calls_confirmation": "Delete all calls from the list?",
+ "app_desktop_unlock": "UNLOCK",
+ "app_desktop_menu": "MENU",
+ "app_desktop_emergency": "SOS",
+ "app_desktop_info": "Info",
+ "app_desktop_info_mmi_none_specified_failed": "Operation failed",
+ "app_desktop_info_mmi_none_specified_success": "Operation successful",
+ "app_desktop_info_mmi_common_failed": "failed",
+ "app_desktop_info_mmi_common_no_message": "not",
+ "app_desktop_info_mmi_common_mmi_not_supported": "not supported",
+ "app_desktop_info_mmi_common_enabled": "enabled",
+ "app_desktop_info_mmi_common_disabled": "disabled",
+ "app_desktop_info_mmi_common_voice": "voice",
+ "app_desktop_info_mmi_common_data": "data",
+ "app_desktop_info_mmi_common_fax": "FAX",
+ "app_desktop_info_mmi_common_sync": "sync",
+ "app_desktop_info_mmi_common_async": "async",
+ "app_desktop_info_mmi_common_all_disabled": "all bearer services disabled",
+ "app_desktop_info_mmi_common_deactivated": "service was deactivated",
+ "app_desktop_info_mmi_common_activated": "service was activated",
+ "app_desktop_info_mmi_common_query": "query",
+ "app_desktop_info_mmi_clir_according_to_subscription": "CLIR according to subscription",
+ "app_desktop_info_mmi_clir_enabled": "CLIR enabled",
+ "app_desktop_info_mmi_clir_disabled": "CLIR diasbled",
+ "app_desktop_info_mmi_clir_not_provisioned": "CLIR not provisioned",
+ "app_desktop_info_mmi_clir_permanent_provisioned": "CLIR permanently provisioned",
+ "app_desktop_info_mmi_clir_unknown": "CLIR unknown",
+ "app_desktop_info_mmi_clir_temporary_restricted": "CLIR temporarily restricted",
+ "app_desktop_info_mmi_clir_temporary_allowed": "CLIR temporarily allowed",
+ "app_desktop_info_mmi_registration_failed": "Registration failed",
+ "app_desktop_info_mmi_registration_success": "Registration was successful",
+ "app_desktop_info_mmi_erasure_failed": "Erasure failed",
+ "app_desktop_info_mmi_erasure_success": "Erasure was successful",
+ "app_desktop_info_mmi_disabling_failed": "Service disabling failed",
+ "app_desktop_info_mmi_disabling_success": "Service has been disabled",
+ "app_desktop_info_mmi_enabling_failed": "Service enabling failed",
+ "app_desktop_info_mmi_enabling_success": "Service has been enabled",
+ "app_desktop_info_mmi_call_forwarding_disabled": "call forwarding disabled",
+ "app_desktop_info_mmi_call_barring_activated": "Call barring was activated",
+ "app_desktop_info_mmi_call_barring_deactivated": "Call barring was deactivated",
+ "app_desktop_info_mmi_clip_activated": "CLIP activated",
+ "app_desktop_info_mmi_clip_deactivated": "CLIP deactivated",
+ "app_desktop_info_mmi_clip_not_provisioned": "CLIP not provisioned",
+ "app_desktop_info_mmi_clip_provisioned": "CLIP provisioned",
+ "app_desktop_info_mmi_clip_unknown": "CLIP unknown",
+ "app_desktop_info_mmi_call_waiting_activated": "Call waiting was activated",
+ "app_desktop_info_mmi_call_waiting_deactivated": "Call waiting was deactivated",
+ "app_desktop_info_mmi_call_forwarding": "Call forwarding",
+ "app_desktop_info_mmi_call_barring": "Call barring",
+ "app_desktop_info_mmi_call_waiting": "Call waiting",
+ "app_desktop_info_mmi_clip": "Caller ID displayed (CLIP)",
+ "app_desktop_info_mmi_clir": "Caller ID suppressed (CLIR)",
+ "app_desktop_info_mmi_imei": "IMEI (MEID)",
+ "app_desktop_info_mmi_result_success": "Success",
+ "app_desktop_info_mmi_result_failed": "Failed",
+ "sim_header_setup": "<text><token>$SIM</token> setup</text>",
+ "sim_enter_pin_unlock": "<text>Enter the PIN code to set up <br></br> the <token>$PINTYPE</token> card:</text>",
+ "sim_enter_enter_current": "<text>Type current Pin Code:</text>",
+ "sim_change_pin": "Change PIN code",
+ "sim_enter_new_pin": "Enter new PIN code:",
+ "sim_confirm_new_pin": "Confirm new PIN code:",
+ "sim_setup_wrong_pin": "<text>Wrong PIN code. You have<br></br><token>$ATTEMPTS</token> attempts left.</text>",
+ "sim_setup_wrong_pin_last_attempt": "<text>Wrong PIN code. You have<br></br>1 attempt left.</text>",
+ "sim_wrong_pin_confirmation": "Wrong PIN code.",
+ "sim_pin_changed_successfully": "PIN code changed successfully",
+ "sim_cme_error": "<text>SIM card<br></br>CME error:<token>$CMECODE</token></text>",
+ "sim_puk_blocked": "<text>The SIM card is blocked.<br></br>Please, contact the operator.</text>",
+ "sim_setup_enter_puk": "<text>The SIM card is blocked.<br></br>To unblock it, type the PUK code:</text>",
+ "sim_setup_wrong_puk": "<text>Wrong PUK code.<br></br>You have <token>$ATTEMPTS</token> attempts left</text>",
+ "sim_setup_wrong_puk_last_attempt": "<text>Wrong PUK code.<br></br>You have 1 attempt left</text>",
+ "sim_setup_wrong_puk_last_attempt_warning": "<text>If the code is wrong this time, the<br></br>SIM card will be blocked and you'll<br></br>have to contact the operator.</text>",
+ "sim_card_pin_disabled": "SIM card pin disabled",
+ "sim_card_pin_enabled": "SIM card pin enabled",
+ "sim_card_cant_connect": "<text>Cannot connect to <token>$SIM</token> card.<br></br>Please insert card.</text>",
+ "sim_card_not_ready": "<text>Waiting for Modem to start.<br></br>This may take a moment.</text>",
+ "app_desktop_press_to_unlock": "<text size='27'>Press <b>Unlock</b> and then <b>#</b></text>",
+ "app_desktop_press_to_complete_unlock": "<text size='27'>Press <b>#</b> to unlock</text>",
+ "app_desktop_unread_messages": "<text>Unread <b>messages</b></text>",
+ "app_desktop_missed_calls": "<text>Missed <b>calls</b></text>",
+ "app_desktop_alarm_snooze": "<text>Snooze</text>",
+ "app_desktop_menu_phone": "CALLS",
+ "app_desktop_menu_contacts": "CONTACTS",
+ "app_desktop_menu_messages": "MESSAGES",
+ "app_desktop_menu_calendar": "CALENDAR",
+ "app_desktop_menu_alarm": "ALARM",
+ "app_desktop_menu_meditation": "MEDITATION",
+ "app_desktop_menu_music": "MUSIC",
+ "app_desktop_menu_tools": "TOOLS",
+ "app_desktop_menu_settings": "SETTINGS",
+ "app_desktop_menu_title": "Menu",
+ "app_desktop_tools_title": "Tools",
+ "app_desktop_tools_notes": "NOTES",
+ "app_desktop_tools_calculator": "CALCULATOR",
+ "app_desktop_tools_antenna": "ANTENNA TEST",
+ "app_desktop_poweroff_title": "Turn off",
+ "app_desktop_poweroff_question": "Turn off the phone?",
+ "app_desktop_show": "SHOW",
+ "app_desktop_calls": "CALLS",
+ "app_desktop_clear": "CLEAR",
+ "app_desktop_clear_all": "CLEAR ALL",
+ "app_desktop_replay": "REPLY",
+ "app_popup_volume_text": "VOLUME",
+ "app_popup_bt_volume_text": "BLUETOOTH VOLUME",
+ "app_popup_music_volume_text": "MUSIC VOLUME",
+ "app_popup_call_volume_text": "CALL VOLUME",
+ "app_popup_muted_text": "MUTED",
+ "app_popup_snooze_text": "SNOOZE",
+ "app_popup_alarm_text": "alarm",
+ "app_popup_alarm_snoozed_till": "snoozed till",
+ "app_call_call": "CALL",
+ "app_call_clear": "CLEAR",
+ "app_call_reject": "REJECT",
+ "app_call_answer": "ANSWER",
+ "app_call_message": "MESSAGE",
+ "app_call_end_call": "END CALL",
+ "app_call_emergency": "Emergency call",
+ "app_call_is_calling": "is calling",
+ "app_call_calling": "calling...",
+ "app_call_call_ended": "call ended",
+ "app_call_call_rejected": "call rejected",
+ "app_call_contact": "CONTACT",
+ "app_call_mute": "MUTE",
+ "app_call_muted": "MUTED",
+ "app_call_speaker": "SPEAKER",
+ "app_call_speaker_on": "SPEAKER ON",
+ "app_call_bluetooth": "BLUETOOTH",
+ "app_call_no_sim": "No SIM.\n\nTo make a call,\nplease insert a SIM card.",
+ "app_call_no_network_connection": "No Network Connection.",
+ "app_call_call_request_failed": "Something went wrong.",
+ "app_call_offline": "You're Offline.\n\nTo make a call,\n switch the mode.",
+ "app_sms_offline": "You're Offline.\n\nTo send message,\n switch the mode.",
+ "app_call_emergency_text": "Emergency call",
+ "app_call_wrong_emergency": "Can't make a call.\n$NUMBER is not an emergency number.",
+ "app_messages_title_main": "Messages",
+ "app_messages_no_messages": "<text align='center' color='4'>No messages yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_messages_thread_delete_confirmation": "Delete this conversation?",
+ "app_messages_message_delete_confirmation": "Delete this message?",
+ "app_messages_thread_no_result": "There are no results",
+ "app_messages_message": "Message",
+ "app_messages_templates": "Templates",
+ "app_messages_no_sim": "No SIM.\n\nTo send a SMS,\nplease insert a SIM card.",
+ "app_messages_thread_draft": "Draft: ",
+ "app_messages_thread_not_sent": "Not sent: ",
+ "app_messages_thread_you": "You: ",
+ "app_onboarding_title": "Onboarding",
+ "app_onboarding_start_configuration": "<text weight='light' size='46'><p>Hello!</p></text><br></br><text weight='regular' size='27'>Let's configure your Mudita Pure.</text>",
+ "app_onboarding_eula_license": "License agreement (EULA)",
+ "app_onboarding_select_sim": "Choose active SIM",
+ "app_onboarding_select_sim_description": "<text>Only one SIM can be active at a time.<br></br>You can choose it now and switch in<br></br>the Settings whenever needed.</text>",
+ "app_onboarding_no_sim_selected_title": "SIM setup",
+ "app_onboarding_no_sim_selected_description": "<text>No SIM card set up.<br></br>To connect to network, set up <br></br> SIM cards in Settings.</text>>",
+ "app_onboarding_title_configuration": "Configuration",
+ "app_onboarding_title_update_info": "MuditaOS update",
+ "app_onboarding_skip_confirm": "<text>SIM setup is required for network connection. Skip the setup anyway? </text>",
+ "app_onboarding_configuration_successful": "<text>Your Mudita Pure<br></br>is ready to use.</text>",
+ "app_onboarding_no_configuration": "<text>Your Mudita Pure has not been<br></br>configured. You can go to<br></br>Settings to set it up.</text>",
+ "app_onboarding_update_info": "<text>The current version of MuditaOS is<br></br><token>$VERSION</token><br></br> Updates with new features and fixes appear often.<br></br>To update your Phone please <br></br> visit: </text><text weight='bold' size='27'>www.mudita.com/updateos</text><br></br><text>and follow the instructions.</text>",
+ "app_settings_title_main": "Settings",
+ "app_settings_advanced": "Advanced",
+ "app_settings_bt": "Bluetooth",
+ "app_settings_bluetooth_add_device": "Add device",
+ "app_settings_bluetooth_all_devices": "All devices",
+ "app_settings_bluetooth_searching_devices": "Searching devices... \nIt may take a moment.",
+ "app_settings_bluetooth_main": "Bluetooth",
+ "app_settings_bluetooth_phone_name": "Phone name",
+ "app_settings_bluetooth_phone_visibility": "Phone visibility",
+ "app_settings_bluetooth_init_error_message": "<text weight='regular' size='27'>Bluetooth initialization process has failed.</text>",
+ "app_settings_bluetooth_pairing_error_message": "<text weight='regular' size='27'>Pairing process has failed.<br></br>Check the device and </text> <text weight='bold' size='27'>TRY AGAIN.</text>",
+ "app_settings_bluetooth_unpairing_error_message": "<text weight='regular' size='27'>Unpairing process has failed.<br></br>Check the device and </text> <text weight='bold' size='27'>TRY AGAIN.</text>",
+ "app_settings_bluetooth_connecting_error_message": "<text weight='regular' size='27'>Connection process has failed.<br></br>Check the device and </text> <text weight='bold' size='27'>TRY AGAIN.</text>",
+ "app_settings_net": "Network",
+ "app_settings_disp_key": "Display and keypad",
+ "app_settings_display_display_light": "Display light",
+ "app_settings_display_dark_mode": "Dark mode (Beta)",
+ "app_settings_display_light_main": "Frontlight",
+ "app_settings_display_light_auto": "Automatic",
+ "app_settings_display_light_brightness": "Brightness",
+ "app_settings_display_font_size": "Font size",
+ "app_settings_display_locked_screen": "Locked screen",
+ "app_settings_display_keypad_light": "Keypad light",
+ "app_settings_display_input_language": "Input language",
+ "app_settings_display_wallpaper": "Wallpaper",
+ "app_settings_display_wallpaper_logo": "Mudita logo",
+ "app_settings_display_wallpaper_clock": "Clock",
+ "app_settings_display_wallpaper_quotes": "Quotes",
+ "app_settings_display_wallpaper_edit_quotes": "Edit quotes",
+ "app_settings_display_wallpaper_edit_custom_quotes": "Edit custom quotes",
+ "app_settings_display_wallpaper_quotes_edit": "Edit",
+ "app_settings_display_wallpaper_quotes_delete": "Delete",
+ "app_settings_display_wallpaper_quotes_new": "New quote",
+ "app_settings_display_wallpaper_quotes_delete_confirmation": "Delete this quote?",
+ "app_settings_display_wallpaper_quotes_delete_success": "Quote deleted.",
+ "app_settings_display_wallpaper_quotes_note": "Note",
+ "app_settings_display_wallpaper_quotes_author": "Author",
+ "app_settings_display_wallpaper_quotes_our_favourites": "Our favorites",
+ "app_settings_display_wallpaper_quotes_custom": "Custom",
+ "app_settings_display_wallpaper_quotes_categories": "Select categories",
+ "app_settings_system": "System",
+ "app_settings_apps": "Apps",
+ "app_settings_apps_phone": "Phone",
+ "app_settings_apps_messages": "Messages",
+ "app_settings_show_unread_first": "Show unread first",
+ "app_settings_apps_alarm_clock": "Alarm clock",
+ "app_settings_apps_alarm_clock_manual_volume": "Manual sound volume",
+ "app_settings_vibration": "Vibration",
+ "app_settings_sound": "Sound",
+ "app_settings_volume": "Volume",
+ "app_settings_call_ringtome": "Call ringtone",
+ "app_settings_message_sound": "Message sound",
+ "app_settings_notification_sound": "Notification sound",
+ "app_settings_Templates": "Templates",
+ "app_settings_title_torch": "Torch",
+ "app_settings_torch_sunset_red_light_option": "Sunset red light",
+ "app_settings_torch_nightshift_time_option": "Nightshift time",
+ "app_settings_torch_description": "In the nightshift, the torch will use\nsunset red light so it won't disturb\nyour and others sleep.",
+ "app_settings_title_nightshift": "Nightshift",
+ "app_settings_nightshift_from": "From",
+ "app_settings_nightshift_to": "To",
+ "app_settings_date_and_time": "Date and time",
+ "app_settings_date_and_time_automatic_date_and_time": "Automatic date and time",
+ "app_settings_date_and_time_change_date_and_time": "Change date and time",
+ "app_settings_date_and_time_automatic_time_zone": "Automatic time zone",
+ "app_settings_date_and_time_change_time_zone": "Change time zone",
+ "app_settings_date_and_time_time_format": "Time format",
+ "app_settings_date_and_time_date_format": "Date format",
+ "app_settings_date_and_time_time_zone": "Time zone",
+ "app_settings_title_day": "Day",
+ "app_settings_title_month": "Month",
+ "app_settings_title_year": "Year",
+ "app_settings_title_time": "Time",
+ "app_settings_cellular_passthrough": "Cellular <-> USB",
+ "app_settings_display": "Display",
+ "app_settings_phone_modes": "Phone modes",
+ "app_settings_security": "Security",
+ "app_settings_language": "Language",
+ "app_settings_factory_reset": "Factory reset",
+ "app_settings_display_factory_reset_confirmation": "You need to restart your Pure \nto finalize factory reset.\n Turn off the phone now?",
+ "app_settings_about_your_pure": "About your Pure",
+ "app_settings_technical_information": "Technical Information",
+ "app_settings_tech_info_model": "Model",
+ "app_settings_tech_info_serial_number": "Serial number",
+ "app_settings_tech_info_os_version": "OS Version",
+ "app_settings_tech_info_imei": "IMEI",
+ "app_settings_tech_info_battery": "Battery",
+ "app_settings_tech_info_pcb_mb": "pcbMB",
+ "app_settings_tech_info_pcb_lm": "pcbLM",
+ "app_settings_tech_info_pcb_um": "pcmUM",
+ "app_settings_tech_info_pcb_am": "pcbAM",
+ "app_settings_certification": "Certification",
+ "app_settings_us_fcc_id": "US FCC ID",
+ "app_settings_canada_ic": "Canada IC",
+ "app_settings_europe": "Europe",
+ "app_settings_sar": "SAR",
+ "app_settings_about": "About Mudita Pure",
+ "app_settings_title_languages": "Language selection",
+ "app_settings_network_sim_cards": "SIM cards",
+ "app_settings_network_active_card": "Active card",
+ "app_settings_network_operator_auto_select": "Operator auto-select",
+ "app_settings_network_all_operators": "All operators",
+ "app_settings_network_pin_settings": "PIN settings",
+ "app_settings_network_pin": "PIN",
+ "app_settings_network_pin_change_code": "Change PIN code",
+ "app_settings_network_import_contacts": "Import contacts",
+ "app_settings_network_import_contacts_duplicates": "Duplicates from SIM",
+ "app_settings_network_import_contacts_from_sim_card": "Import contacts from SIM card",
+ "app_settings_network_import_contacts_from_sim_card_reading": "<text>Importing in progress...<br></br>Please wait a moment.</text>",
+ "app_settings_network_import_contacts_from_sim_card_no_contacts": "<text>There are no contacts<br></br>on this SIM card.</text>",
+ "app_settings_network_import_contacts_from_sim_card_duplicates": "<text>We found <token>$DUPLICATES</token> duplicates. Do you want<br></br>to import duplicated contacts and<br></br>replace existing ones.</text>",
+ "app_settings_network_import_contacts_from_sim_card_success": "Contacts imported successfully.",
+ "app_settings_network_sim1": "SIM1",
+ "app_settings_network_sim2": "SIM2",
+ "app_settings_network_sim_none": "No SIM",
+ "app_settings_network_voice_over_lte": "VoLTE (experimental)",
+ "app_settings_network_apn_settings": "APN settings",
+ "app_settings_toggle_on": "ON",
+ "app_settings_toggle_off": "OFF",
+ "app_settings_security_phone_lock": "Lock screen passcode",
+ "app_settings_display_security_autolock": "Auto lock",
+ "app_settings_security_change_phone_lock": "Change passcode",
+ "phone_lock_unlock": "<text>Enter the passcode<br></br>to unlock:</text>",
+ "phone_lock_blocked_information": "<text>Wrong passcode.<br></br>Try again in <token>$TIME</token>.</text>",
+ "phone_lock_blocked_information_seconds": " seconds",
+ "phone_lock_blocked_information_minute": "a minute",
+ "phone_lock_blocked_information_minutes": " minutes",
+ "phone_lock_notification": "<text>Passcode lock for <token>$TIME</token></text>",
+ "phone_lock_unlock_invalid": "<text>Wrong passcode.<br></br>Please try again.</text>",
+ "phone_lock_blocked": "Sorry, phone blocked",
+ "phone_lock_current": "Type current passcode",
+ "phone_lock_enter_new": "Enter new passcode",
+ "phone_lock_confirm_new": "Confirm new passcode",
+ "phone_lock_invalid": "Wrong passcode!",
+ "phone_lock_changed_successfully": "Passcode changed successfully!",
+ "phone_lock_disabled": "Passcode disabled!",
+ "phone_lock_set": "<text>Set passcode that unlocks <br></br> the phone</text>",
+ "phone_lock_confirm": "Confirm the passcode",
+ "phone_lock_invalid_retry": "<text>Wrong passcode. <br></br> Configure passcode again.</text>",
+ "phone_lock_configure": "Configure passcode",
+ "app_settings_security_usb_passcode": "USB security",
+ "app_settings_apn_settings_no_apns": "<text align='center' color='5'>No APNs yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_settings_apn_options_delete": "Delete",
+ "app_settings_apn_options_edit": "Edit",
+ "app_settings_apn_options_set_as_default": "Set as default",
+ "app_settings_new_edit_apn": "New/Edit APN",
+ "app_settings_apn_name": "Name",
+ "app_settings_apn_APN": "APN",
+ "app_settings_apn_username": "Username",
+ "app_settings_apn_password": "Password",
+ "app_settings_apn_authtype": "Authentication type",
+ "app_settings_apn_apntype": "APN type",
+ "app_settings_apn_apnprotocol": "APN protocol",
+ "app_settings_title_color_test": "Display available colors",
+ "app_settings_toolbar_reset": "RESET",
+ "app_settings_option_connected": "CONNECTED",
+ "app_settings_option_connected_audio": "CONNECTED AUDIO",
+ "app_settings_option_connected_voice": "CONNECTED VOICE",
+ "app_settings_option_connected_both": "CONNECTED VOICE, AUDIO",
+ "app_settings_option_connecting": "CONNECTING",
+ "app_settings_option_pairing": "PAIRING",
+ "app_settings_title_do_not_disturb": "Do not disturb",
+ "app_settings_title_offline": "Offline",
+ "app_settings_title_connection_frequency": "Connection frequency",
+ "app_settings_connected": "Connected",
+ "app_settings_notifications_when_locked": "Notifications when locked",
+ "app_settings_calls_from_favorites": "Calls from favorites",
+ "app_settings_allow": "Allow",
+ "app_settings_no_network_connection_flight_mode": "Flight mode",
+ "app_settings_messages_only": "Messages only",
+ "app_settings_info_dnd": "Silently receive all notifications. You can allow full notifications from favorite contacts.",
+ "app_settings_info_offline_flight_mode": "Fully disconnected. Calls, messages and tethering are unavailable.",
+ "app_settings_info_offline_messages_only": "Send and download messages based on connection intervals. No calls nor tethering.",
+ "app_phonebook_title_main": "Contacts",
+ "common_search_uc": "Search",
+ "common_search_results": "Search results",
+ "app_phonebook_search_no_results": "No contacts found.",
+ "app_phonebook_no_contacts": "<text align='center' color='4'>No contacts yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_phonebook_no_contacts_yet": "<text align='center' color='4'>No contacts yet.</text>",
+ "app_phonebook_contact_title": "Add contact",
+ "app_phonebook_contact_no_name": "no name",
+ "app_phonebook_contact_information": "Information",
+ "app_phonebook_contact_flag_fav": "FAVORITES",
+ "app_phonebook_contact_flag_speed_dial": "SPEED DIAL",
+ "app_phonebook_contact_flag_ice": "ICE",
+ "app_phonebook_contact_flag_blocked": "BLOCKED",
+ "app_phonebook_ice_contacts_title": "Emergency Contacts",
+ "app_phonebook_favorite_contacts_title": "Favorites",
+ "app_phonebook_duplicate_numbers": "<text>This number is assigned to \n <token>$CONTACT_FORMATTED_NAME$</token>. Replace it?</text>",
+ "app_phonebook_duplicate_speed_dial": "<text>Number <token>$CONTACT_SPEED_DIAL$</token> is assigned to \n <token>$CONTACT_FORMATTED_NAME$</token>. Replace it?</text>",
+ "app_phonebook_duplicate_speed_dial_title": "<text>Speed dial key (<token>$CONTACT_SPEED_DIAL$</token>)</text>",
+ "app_phonebook_options_edit": "Edit contact",
+ "app_phonebook_options_block": "Block",
+ "app_phonebook_options_block_confirm": "Block this contact?",
+ "app_phonebook_options_block_notification": "Contact blocked.",
+ "app_phonebook_options_unblock": "Unblock",
+ "app_phonebook_options_unblock_confirm": "Unblock this contact?",
+ "app_phonebook_options_unblock_notification": "Contact unblocked.",
+ "app_phonebook_options_delete": "Delete",
+ "app_phonebook_options_delete_confirm": "Do you really want to delete\nthis contact?",
+ "app_phonebook_options_delete_notification": "This contact has been deleted\nsuccessfully.",
+ "app_phonebook_options_forward_namecard": "Forward namecard",
+ "app_phonebook_options_send_sms": "Send via SMS",
+ "app_phonebook_new_contact_first_name": "First name",
+ "app_phonebook_new_contact_last_name": "Last name",
+ "app_phonebook_new_contact_number": "Phone number",
+ "app_phonebook_new_contact_second_number": "Second phone number",
+ "app_phonebook_new_contact_email": "Email",
+ "app_phonebook_new_contact_address": "Address",
+ "app_phonebook_new_contact_note": "Note",
+ "app_phonebook_new_speed_dial_key": "Speed dial key",
+ "app_phonebook_new_contact_invalid_number": "<text>Cannot save this contact.<br></br>The phone number you entered <br></br>is in an invalid format.</text>",
+ "app_phonebook_new_add_to_fav": "Add to favorites",
+ "app_phonebook_new_add_to_ice": "Emergency Contact (ICE)",
+ "app_phonebook_check": "CHECK",
+ "app_phonebook_uncheck": "UNCHECK",
+ "app_phonebook_multiple_numbers_first": "Number",
+ "app_phonebook_multiple_numbers_second": "Second number",
+ "app_meditation_title_main": "Meditation timer",
+ "app_meditation_preparation_time": "Preparation time",
+ "app_meditation_put_down_phone_and_wait": "<text>Put down the phone<br>and wait for the gong.</text>",
+ "app_meditation_thank_you_for_session": "<text>Thank you for this<br>meditation session.</text>",
+ "app_meditation_option_show_counter": "Show meditation counter",
+ "app_meditation_interval_chime": "Interval chime",
+ "app_meditation_interval_none": "None",
+ "app_meditation_interval_every_x_minutes": "Every %0 minutes",
+ "app_meditation_minute": "MINUTE",
+ "app_meditation_minutes": "MINUTES",
+ "app_music_player_all_songs": "<text><b>All songs</b></text>",
+ "app_music_player_artists": "<text color='9'>Artists</text>",
+ "app_music_player_albums": "<text color='9'>Albums</text>",
+ "app_music_player_playlists": "<text color='9'>Playlists</text>",
+ "app_music_player_uknown_title": "Unknown Title",
+ "app_music_player_uknown_artist": "Unknown Artist",
+ "app_music_player_music_library_window_name": "Music Library",
+ "app_music_player_music_library": "MUSIC LIBRARY",
+ "app_music_player_quit": "QUIT",
+ "app_music_player_empty_track_notification": "Please choose a song from library",
+ "app_music_player_start_window_notification": "<text color='5'>Press <b>down arrow</b> to choose<br></br> a song from the library</text>",
+ "app_music_player_music_empty_window_notification": "<text color='5'>No songs yet</text>",
+ "app_special_input_window": "Special characters",
+ "app_emoji_input_window": "Emoji",
+ "sms_add_rec_num": "Add contact or type a number",
+ "sms_title_message": "New message",
+ "sms_call_text": "Call ",
+ "sms_resend_failed": "Send again",
+ "sms_delete_conversation": "Delete conversation",
+ "sms_forward_message": "Forward message",
+ "sms_copy": "Copy",
+ "sms_delete_message": "Delete message",
+ "sms_use_template": "Use template",
+ "sms_paste": "Paste",
+ "sms_temp_reply": "Reply",
+ "sms_mark_read": "Mark as read",
+ "sms_mark_unread": "Mark as unread",
+ "app_desktop_update": "Update",
+ "app_desktop_update_to": "Update to",
+ "app_desktop_update_apply": "Do you want to apply this update?",
+ "app_desktop_update_current": "Current",
+ "app_desktop_update_start": "Update start",
+ "app_desktop_update_size": "size",
+ "app_desktop_update_bytes": "bytes",
+ "app_desktop_update_unpacking": "Unpacking",
+ "app_desktop_update_preparing": "Preparing MuditaOS update ver.",
+ "app_desktop_update_muditaos": "MuditaOS update",
+ "app_desktop_update_in_progress": "Update in progress...",
+ "app_desktop_update_ready_for_reset": "Ready for reset...",
+ "app_desktop_update_success": "MuditaOS has been updated to ver. $VERSION succesfully.",
+ "app_call_private_number": "Private number",
+ "app_call_ending_call": "Disconnecting call",
+ "tethering": "Tethering",
+ "tethering_turn_off_question": "Turn tethering off?",
+ "tethering_enable_question": "<text>You're connected to the computer.<br />Turn tethering on?<br /><text color='5'>(some functions may be disabled)</text></text>",
+ "tethering_phone_mode_change_prohibited": "<text>Tethering is on.<br /><br />Other modes (Connected, DND,<br />Offline) are overriden by this mode<br />and are not working.</text>",
+ "tethering_menu_access_decline": "<text>Tethering is on.<br /><br />To access menu,<br />turn tethering off.</text>",
+ "bluetooth_popup": "Bluetooth",
+ "bluetooth_popup_pin": "Enter PIN:",
+ "bluetooth_popup_passkey": "Enter passkey:",
+ "bluetooth_popup_pair_cancel_code": "<text>Device </text><text weight='bold'><token>$DEVICE</token></text><text> would like to pair<br /> with your Pure. Please confirm<br /> the code: <text align='center' weight='bold'><token>$CODE</token></text></text>",
+ "bluetooth_popup_pair_cancel_no_code": "<text>Device </text><text weight='bold'><token>$DEVICE</token></text><text> would like to pair with your Pure.</text>",
+ "bluetooth_popup_confirm": "Confirm",
+ "bluetooth_popup_cancel": "Cancel",
+ "bluetooth_info_popup_success": "<text>Your phone is paired with: <br></br></text><text weight='bold'><token>$DEVICE</token></text>",
+ "bluetooth_info_popup_error": "<text>Pairing process with </text><text weight='bold'><token>$DEVICE</token></text><br></br><text> has failed. Error code: <token>$ERROR</token></text>",
+ "app_bell_settings_time_units_time_fmt_top_message": "Time format",
+ "app_bell_settings_time_units_time_message": "Time",
+ "app_bellmain_alarm": "Alarm",
+ "app_bellmain_bedtime": "Bedtime",
+ "app_bell_bedtime_notification": "It is your bedtime",
+ "app_bellmain_power_nap": "Power nap",
+ "app_bellmain_meditation_timer": "Meditation",
+ "app_bellmain_background_sounds": "Relaxation",
+ "app_bellmain_settings": "Settings",
+ "app_bellmain_main_window_title": "Mudita Harmony",
+ "app_bell_meditation_timer": "Meditation",
+ "app_bell_meditation_settings": "Settings",
+ "app_bell_meditation_start": "Meditate now",
+ "app_bell_meditation_statistics": "Statistics",
+ "app_bell_meditation_chime_volume": "Chime volume",
+ "app_bell_meditation_chime_interval": "Chime interval",
+ "app_bell_meditation_chime_interval_bottom": "of the meditation",
+ "app_bell_meditation_start_delay": "Start delay",
+ "app_bell_meditation_progress": "Meditation timer",
+ "app_bell_meditation_interval_none": "None",
+ "app_bell_meditation_put_down_and_wait": "<text>Put down Mudita Harmony<br>and wait for the gong</text>",
+ "app_bell_meditation_thank_you_for_session": "<text>Thank you for<br>the session</text>",
+ "app_bell_onboarding_welcome_message": "<text>Mudita Harmony<br/>is switched OFF</text>",
+ "app_bell_onboarding_info_rotate": "<text weight='regular' size='38'>Rotate </text><text weight='light' size='38'>to select</text>",
+ "app_bell_onboarding_info_light_click": "<text weight='regular' size='38'>Light click </text><text weight='light' size='38'>to continue</text>",
+ "app_bell_onboarding_info_deep_click_warning": "<text weight='light' size='38'>You've </text><text weight='regular' size='38'>deep pressed</text>",
+ "app_bell_onboarding_info_deep_click_correction": "<text weight='light' size='38'>Be more gentle,<br></br>try </text><text weight='regular' size='38'>light click </text><text weight='light' size='38'>this time</text>",
+ "app_bell_onboarding_welcome": "Welcome",
+ "app_bell_settings_advanced": "Advanced",
+ "app_bell_settings_time_units": "Time",
+ "app_bell_settings_temp_scale": "Temperature scale",
+ "app_bell_settings_language": "Language",
+ "app_bell_settings_layout": "Clock face",
+ "app_bell_settings_about": "About",
+ "app_bell_settings_about_product": "Mudita Harmony",
+ "app_bell_settings_about_version": "<text>OS version: <token>$VERSION</token></text>",
+ "app_bell_settings_about_storage_title": "Storage",
+ "app_bell_settings_about_storage_text": "<text><token>$USED_MEMORY</token>MB of <token>$TOTAL_MEMORY</token>MB used</text>",
+ "app_bell_settings_about_info_title": "Manual & certification info",
+ "app_bell_settings_about_info_text": "www.mudita.com",
+ "app_bell_settings_alarm_settings": "Alarm",
+ "app_bell_settings_alarm_settings_title": "Alarm settings",
+ "app_bell_settings_alarm_settings_tone": "Alarm tone",
+ "app_bell_settings_alarm_settings_volume": "Alarm volume",
+ "app_bell_settings_alarm_settings_light": "Alarm light",
+ "app_bell_settings_alarm_settings_prewake_up": "Pre-wake up",
+ "app_bell_settings_alarm_settings_prewake_up_chime_top_description": "Pre-wake up chime",
+ "app_bell_settings_alarm_settings_prewake_up_chime_bottom_description": "before the alarm",
+ "app_bell_settings_alarm_settings_prewake_up_chime_tone": "Pre-wake up chime tone",
+ "app_bell_settings_alarm_settings_prewake_up_chime_volume": "Pre-wake up chime volume",
+ "app_bell_settings_alarm_settings_prewake_up_light_top_description": "Pre-wake up light",
+ "app_bell_settings_alarm_settings_prewake_up_light_bottom_description": "before the alarm",
+ "app_bell_settings_alarm_settings_alarm_tone_and_light": "Main alarm",
+ "app_bell_settings_bedtime_tone": "Bedtime tone",
+ "app_bell_settings_bedtime_settings_tone": "Bedtime tone",
+ "app_bell_settings_bedtime_settings_volume": "<text>Bedtime tone<br />volume</text>",
+ "app_bell_settings_home_view": "Home view",
+ "app_bell_settings_turn_off": "Turn off",
+ "app_bell_settings_alarm_settings_snooze": "Snooze",
+ "app_bell_settings_alarm_settings_snooze_length": "Snooze length",
+ "app_bell_settings_alarm_settings_snooze_chime_interval": "Snooze chime interval",
+ "app_bell_settings_alarm_settings_snooze_chime_interval_bot_desc": "<text>recurring during<br />snooze</text>",
+ "app_bell_settings_alarm_settings_snooze_chime_tone": "Snooze chime tone",
+ "app_bell_settings_alarm_settings_snooze_chime_volume": "Snooze chime volume",
+ "app_bellmain_home_screen_bottom_desc": "Next alarm will ring",
+ "app_bellmain_home_screen_bottom_desc_in": "in",
+ "app_bellmain_home_screen_bottom_desc_and": "&",
+ "app_bellmain_home_screen_bottom_desc_less_than": "less than",
+ "app_bellmain_home_screen_bottom_desc_dp": "Deep press to activate",
+ "app_bell_alarm_deactivated": "<text>Alarm deactivated</text>",
+ "app_bell_alarm_set_not_active": "<text>Alarm set.<br />Deep press to activate.</text>",
+ "app_bell_settings_frontlight": "Frontlight",
+ "app_bell_settings_frontlight_top_message": "Frontlight intensity",
+ "app_bell_settings_frontlight_mode_top_message": "Frontlight mode",
+ "app_bell_settings_frontlight_mode_auto": "auto",
+ "app_bell_settings_frontlight_mode_on_demand": "on demand",
+ "app_bell_background_sounds_timer_title": "Auto turn off",
+ "app_bell_turn_off_question": "Turn off Mudita Harmony?",
+ "app_bell_goodbye": "Goodbye",
+ "app_bell_reset_message": "<text>Resetting Mudita<br />Harmony</text>",
+ "app_bell_greeting_msg": [
+ "<text>Good Morning!<br />It's a Beautiful Day!</text>",
+ "<text>Rise and shine!<br />Seize the day</text>",
+ "<text>Greetings & Salutations!<br />It's Wake-up time!</text>",
+ "<text>Morning!<br />Enjoy the day!</text>",
+ "<text>Good day to you!<br />Today is a new day.</text>",
+ "<text>It's a Beautiful Day<br />Time to rise & shine</text>",
+ "<text>It's a Brand New Day!<br />Make the most of it!</text>",
+ "<text>Hello!<br />Have an AMAZING DAY</text>",
+ "<text>Bonjour!<br />Let the day begin!</text>",
+ "<text>What a lovely day!<br />Don't stay in bed!</text>",
+ "<text>Hello Sunshine!<br />Go brighten the world!</text>",
+ "<text>Morning Greetings!<br />Go forth with a smile</text>",
+ "<text>Good Morning!<br />It's time to get up!</text>",
+ "<text>Buenos Dias!<br />Rise & shine all day!</text>",
+ "<text>Dzien Dobry!<br />Make it a GREAT day!</text>",
+ "<text>Howdy!<br />Time to take charge!</text>",
+ "<text>Salutations!<br />Salute the day!</text>",
+ "<text>Cześć<br />Welcome to TODAY!</text>",
+ "<text>Ciao!<br />Let's do something amazing!</text>",
+ "<text>Morning is here!<br />A new day has arrived!</text>",
+ "<text>Time to get up!<br />All we have is NOW!</text>",
+ "<text>Hallå!<br />Life is better with Fika!</text>",
+ "<text>Namaste!<br />Make it a GREAT day!</text>",
+ "<text>Ahoy!<br />It's time to set sail</text>",
+ "<text>What's happening!<br />How did you sleep?</text>",
+ "<text>G'day!<br />Take on the day!</text>",
+ "<text>How's it going?<br />Did you sleep well?</text>",
+ "<text>Hej!<br />It's a spectacular day!</text>",
+ "<text>Buon giorno!<br />Everyday is a miracle!</text>",
+ "<text>Hello Sunshine!<br />Make your day sparkle!</text>",
+ "<text>Cheers to the day!<br />The future starts NOW!</text>",
+ "<text>Wakey Wakey!<br />The morning awaits!</text>",
+ "<text>Hejsan!<br />Have a wonderful day!</text>"
+ ],
+ "app_bell_settings_factory_reset": "Factory reset",
+ "app_bell_settings_display_factory_reset_confirmation": "<text>Reset to factory<br></br>settings ?</text>",
+ "app_meditation_summary": "<text>You've meditated for<br />",
+ "app_meditation_countdown_desc": "Starts in",
+ "app_meditation_summary_total": "<text>Total:<br /><token>$VALUE</token></text>",
+ "app_meditation_summary_average": "Average/day:",
+ "app_meditation_summary_title": "<text>Last <token>$VALUE</token> days</text>"
+}
M module-services/service-db/test/test-factory-settings.cpp => module-services/service-db/test/test-factory-settings.cpp +26 -16
@@ 2,23 2,38 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include <Helpers.hpp>
#include <service-db/agents/settings/FactorySettings.hpp>
#include <service-db/EntryPath.hpp>
const std::string valid_json = "{\"serial\" : \"00000000000000\", \"case_colour\" : \"nocase\"}";
const std::string invalid_json = "{\"serial\" : \"00000000000000\", \"case_colour\" : \"nocase\"}}";
+constexpr auto schema = "CREATE TABLE IF NOT EXISTS settings_tab ( path TEXT NOT NULL UNIQUE PRIMARY KEY,value TEXT);";
+
const auto valid_path = "valid.json";
const auto invalid_path = "invalid.json";
-TEST_CASE("Factory Settings")
+namespace
{
-
- SECTION("valid file")
+ void spawnAndFillFile(std::filesystem::path path, std::string content)
{
+ if (std::filesystem::exists(path)) {
+ std::filesystem::remove(path);
+ }
+
auto file = std::fopen(valid_path, "w");
- std::fwrite(valid_json.data(), sizeof(char), valid_json.size(), file);
+ REQUIRE(file != nullptr);
+ std::fwrite(content.data(), sizeof(char), content.size(), file);
std::fclose(file);
+ }
+} // namespace
+
+TEST_CASE("Factory Settings")
+{
+ SECTION("valid file")
+ {
+ spawnAndFillFile(valid_path, valid_json);
settings::FactorySettings factory{valid_path};
auto entries = factory.getMfgEntries();
@@ 30,9 45,7 @@ TEST_CASE("Factory Settings")
SECTION("invalid file")
{
- auto file = std::fopen(invalid_path, "w");
- std::fwrite(invalid_json.data(), sizeof(char), invalid_json.size(), file);
- std::fclose(file);
+ spawnAndFillFile(invalid_path, invalid_json);
settings::FactorySettings factory{invalid_path};
auto entries = factory.getMfgEntries();
@@ 42,24 55,21 @@ TEST_CASE("Factory Settings")
TEST_CASE("Factory Settings Init")
{
- Database::initialize();
+ db::tests::DatabaseUnderTest<Database> db{"settings_v2.db"};
+ REQUIRE(db.get().query(schema));
SECTION("Init db with factory entries")
{
- auto file = std::fopen(valid_path, "w");
- std::fwrite(valid_json.data(), sizeof(char), valid_json.size(), file);
- std::fclose(file);
-
- auto dbPath = purefs::dir::getUserDiskPath() / "settings_v2.db";
- Database db(dbPath.c_str());
+ spawnAndFillFile(valid_path, valid_json);
settings::FactorySettings factory{valid_path};
- factory.initDb(&db);
+ factory.initDb(&db.get());
settings::EntryPath variablePath{
"", "", "", settings::factory::entry_key + std::string("/serial"), settings::SettingsScope::Global};
- auto results = db.query(settings::Statements::getValue, variablePath.to_string().c_str());
+ const auto results = db.get().query(settings::Statements::getValue, variablePath.to_string().c_str());
+ REQUIRE(results);
REQUIRE(results->getRowCount() == 1);
}
}
M module-services/service-db/test/test-service-db-quotes.cpp => module-services/service-db/test/test-service-db-quotes.cpp +23 -9
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
+#include <Helpers.hpp>
#include "test-service-db-quotes.hpp"
#include <purefs/filesystem_paths.hpp>
@@ 11,22 12,37 @@
using namespace Quotes;
-constexpr auto totalNumOfCategories = 3;
-constexpr auto totalNumOfQuotes = 5;
+constexpr auto totalNumOfCategories = 5;
+
+namespace
+{
+ std::filesystem::path getScriptsPath()
+ {
+ const std::string path = __FILE__;
+ const std::filesystem::path scripts = "../../../products/PurePhone/services/db/databases/scripts";
+ return std::filesystem::path{path.substr(0, path.rfind('/'))} / scripts;
+ }
+
+ std::filesystem::path getLanguagePath()
+ {
+ const std::string path = __FILE__;
+ return std::filesystem::path{path.substr(0, path.rfind('/'))};
+ }
+} // namespace
TEST_CASE("Quotes")
{
- Database::initialize();
- auto predefinedDB =
- std::make_unique<Database>((purefs::dir::getUserDiskPath() / "predefined_quotes.db").string().c_str());
- auto customDB = std::make_unique<Database>((purefs::dir::getUserDiskPath() / "custom_quotes.db").string().c_str());
+ db::tests::DatabaseUnderTest<Database> predefinedDb{"predefined_quotes.db", getScriptsPath(), true};
+ db::tests::DatabaseUnderTest<Database> customDb{"custom_quotes.db", getScriptsPath(), true};
+
std::string timestampString{};
std::string quotesString{};
auto settings = std::make_unique<Quotes::SettingsMock>(quotesString, timestampString);
- auto tester = std::make_unique<QuotesAgentTester>(predefinedDB.get(), customDB.get(), std::move(settings));
+ auto tester = std::make_unique<QuotesAgentTester>(&predefinedDb.get(), &customDb.get(), std::move(settings));
SECTION("Get all categories")
{
+ utils::resetAssetsPath(getLanguagePath());
utils::setDisplayLanguage("English");
tester->informLanguageChange();
auto categories = tester->getCategoriesList();
@@ 236,8 252,6 @@ TEST_CASE("Quotes")
// No crash expected
REQUIRE_NOTHROW(tester->readRandomizedQuote());
}
-
- Database::deinitialize();
}
TEST_CASE("Serializer test")
M module-services/service-fileindexer/ServiceFileIndexer.cpp => module-services/service-fileindexer/ServiceFileIndexer.cpp +1 -5
@@ 10,10 10,6 @@
namespace
{
- inline auto getMusicPath()
- {
- return purefs::createPath(purefs::dir::getUserDiskPath(), "music").string();
- }
inline constexpr auto fileIndexerServiceStackSize = 1024 * 5;
} // namespace
@@ 35,7 31,7 @@ namespace service
sys::ReturnCodes ServiceFileIndexer::InitHandler()
{
if (mInotifyHandler.init(shared_from_this())) {
- mInotifyHandler.addWatch(getMusicPath());
+ mInotifyHandler.addWatch(purefs::dir::getUserAudioPath().c_str());
// Start the initial indexer
mStartupIndexer.start(shared_from_this(), service::name::file_indexer);
M module-services/service-fileindexer/include/service-fileindexer/ServiceFileIndexer.hpp => module-services/service-fileindexer/include/service-fileindexer/ServiceFileIndexer.hpp +1 -1
@@ 15,7 15,7 @@ namespace service
class ServiceFileIndexer final : public sys::Service
{
public:
- ServiceFileIndexer(const std::vector<std::string> &paths);
+ explicit ServiceFileIndexer(const std::vector<std::string> &paths);
virtual ~ServiceFileIndexer() = default;
ServiceFileIndexer(const ServiceFileIndexer &) = delete;
ServiceFileIndexer &operator=(const ServiceFileIndexer &) = delete;
M module-vfs/paths/filesystem_paths.cpp => module-vfs/paths/filesystem_paths.cpp +5 -0
@@ 8,6 8,7 @@ namespace
constexpr inline auto PATH_SYS = "/sys";
constexpr inline auto PATH_CONF = "/mfgconf";
constexpr inline auto PATH_USER = "user";
+ constexpr inline auto PATH_DB = "db";
constexpr inline auto PATH_OS = "os";
constexpr inline auto PATH_CURRENT = "current";
constexpr inline auto PATH_PREVIOUS = "previous";
@@ 46,6 47,10 @@ namespace purefs
{
return std::filesystem::path{eMMC_disk} / PATH_USER;
}
+ std::filesystem::path getDatabasesPath() noexcept
+ {
+ return getUserDiskPath() / PATH_DB;
+ }
std::filesystem::path getCurrentOSPath() noexcept
{
M module-vfs/paths/include/purefs/filesystem_paths.hpp => module-vfs/paths/include/purefs/filesystem_paths.hpp +1 -0
@@ 14,6 14,7 @@ namespace purefs
std::filesystem::path getRootDiskPath() noexcept;
std::filesystem::path getMfgConfPath() noexcept;
std::filesystem::path getUserDiskPath() noexcept;
+ std::filesystem::path getDatabasesPath() noexcept;
std::filesystem::path getCurrentOSPath() noexcept;
std::filesystem::path getPreviousOSPath() noexcept;
std::filesystem::path getUpdatesOSPath() noexcept;
M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +1 -1
@@ 15,7 15,7 @@
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
// modules
-#include <module-db/Databases/MultimediaFilesDB.hpp>
+#include <module-db/databases/MultimediaFilesDB.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>
// services
M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +14 -3
@@ 82,7 82,7 @@ include(BinaryAssetsVersions.cmake)
include(AddVersionJson)
add_directories(
- TARGET user_directories
+ TARGET create_user_directories
PREFIX ${CMAKE_BINARY_DIR}/sysroot/sys/user/audio
DEPENDS user_directories_common
DIRECTORIES relaxation
@@ 95,7 95,14 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
PRODUCT BellHybrid
SYSROOT sysroot
LUTS Luts.bin
- DEPENDS user_directories assets updater.bin-target ecoboot.bin-target BellHybrid-boot.bin BellHybrid-version.json-target
+ DEPENDS
+ create_product_databases
+ create_user_directories
+ assets
+ updater.bin-target
+ ecoboot.bin-target
+ BellHybrid-boot.bin
+ BellHybrid-version.json-target
)
add_version_rt1051_json(BellHybrid)
else()
@@ 103,7 110,11 @@ else()
PRODUCT BellHybrid
SYSROOT sysroot
LUTS ""
- DEPENDS user_directories assets BellHybrid-version.json-target
+ DEPENDS
+ create_product_databases
+ create_user_directories
+ assets
+ BellHybrid-version.json-target
)
add_version_linux_json(BellHybrid)
endif()
M products/BellHybrid/apps/application-bell-bedtime/CMakeLists.txt => products/BellHybrid/apps/application-bell-bedtime/CMakeLists.txt +0 -1
@@ 27,7 27,6 @@ target_include_directories(application-bell-bedtime
target_link_libraries(application-bell-bedtime
PRIVATE
app
- bellgui
bell::app-common
bell::db
date::date
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +0 -1
@@ 40,7 40,6 @@ target_link_libraries(application-bell-main
PRIVATE
app
apps-common
- bellgui
i18n
module-gui
service-gui
M products/BellHybrid/apps/application-bell-meditation-timer/data/MeditationCommon.hpp => products/BellHybrid/apps/application-bell-meditation-timer/data/MeditationCommon.hpp +1 -1
@@ 19,7 19,7 @@ namespace app::meditation
inline std::filesystem::path getMeditationAudioPath()
{
- return paths::audio::proprietary() / "Meditation_Gong.mp3";
+ return paths::audio::proprietary() / paths::audio::meditation() / "Meditation_Gong.mp3";
}
} // namespace app::meditation
M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt => products/BellHybrid/apps/application-bell-settings/CMakeLists.txt +0 -1
@@ 121,7 121,6 @@ target_link_libraries(application-bell-settings
PRIVATE
app
bell::audio
- bellgui
bell::db
bell::paths
bell::app-main
M products/BellHybrid/apps/common/include/common/data/BatteryUtils.hpp => products/BellHybrid/apps/common/include/common/data/BatteryUtils.hpp +1 -1
@@ 3,10 3,10 @@
#pragma once
-#include <cstdint>
#include <algorithm>
#include <optional>
#include <string>
+#include <array>
#include <Units.hpp>
M products/BellHybrid/services/db/ServiceDB.cpp => products/BellHybrid/services/db/ServiceDB.cpp +4 -4
@@ 5,8 5,8 @@
#include "agents/MeditationStatsAgent.hpp"
-#include <module-db/Databases/EventsDB.hpp>
-#include <module-db/Databases/MultimediaFilesDB.hpp>
+#include <module-db/databases/EventsDB.hpp>
+#include <module-db/databases/MultimediaFilesDB.hpp>
#include <module-db/Interface/AlarmEventRecord.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>
@@ 77,9 77,9 @@ sys::ReturnCodes ServiceDB::InitHandler()
}
// Create databases
- eventsDB = std::make_unique<EventsDB>((purefs::dir::getUserDiskPath() / "events.db").c_str());
+ eventsDB = std::make_unique<EventsDB>((purefs::dir::getDatabasesPath() / "events.db").c_str());
multimediaFilesDB = std::make_unique<db::multimedia_files::MultimediaFilesDB>(
- (purefs::dir::getUserDiskPath() / "multimedia.db").c_str());
+ (purefs::dir::getDatabasesPath() / "multimedia.db").c_str());
// Create record interfaces
alarmEventRecordInterface = std::make_unique<AlarmEventRecordInterface>(eventsDB.get());
M products/BellHybrid/services/db/agents/MeditationStatsAgent.cpp => products/BellHybrid/services/db/agents/MeditationStatsAgent.cpp +1 -1
@@ 42,7 42,7 @@ namespace service::db::agents
auto MeditationStats::getDbFilePath() -> const std::string
{
- return (purefs::dir::getUserDiskPath() / dbName).string();
+ return (purefs::dir::getDatabasesPath() / dbName).string();
}
auto MeditationStats::getAgentName() -> const std::string
{
M products/BellHybrid/services/db/databases/MeditationStatisticsTable.cpp => products/BellHybrid/services/db/databases/MeditationStatisticsTable.cpp +8 -7
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "MeditationStatisticsTable.hpp"
+#include <Common/Types.hpp>
#include <time.h>
#include <chrono>
#include <date/date.h>
@@ 40,8 41,8 @@ namespace
return {};
}
- const auto retQuery = db->query("SELECT * from %s where timestamp BETWEEN "
- "datetime('now','-%lu %s') and datetime('now');",
+ const auto retQuery = db->query("SELECT * from " str_ " where timestamp BETWEEN "
+ "datetime('now','-" u32_ " %s') and datetime('now');",
tableName,
x,
modifier.data());
@@ 106,16 107,16 @@ namespace db::meditation_stats
auto MeditationStatsTable::add(const TableRow entry) -> bool
{
- return db->execute("INSERT INTO '%s' (timestamp,duration) "
- "VALUES('%s', '%lu') ",
+ return db->execute("INSERT INTO " str_ " (timestamp,duration) "
+ "VALUES(" str_c u32_ ")",
tableName,
prepare_timestamp(entry.timestamp).c_str(),
static_cast<std::uint32_t>(entry.duration.count()));
}
auto MeditationStatsTable::getLimitOffset(const uint32_t offset, const uint32_t limit) -> std::vector<TableRow>
{
- const auto retQuery =
- db->query("SELECT * from '%s' ORDER BY timestamp DESC LIMIT %lu OFFSET %lu;", tableName, limit, offset);
+ const auto retQuery = db->query(
+ "SELECT * from " str_ " ORDER BY timestamp DESC LIMIT " u32_ " OFFSET " u32_ ";", tableName, limit, offset);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return {};
@@ 136,7 137,7 @@ namespace db::meditation_stats
}
auto MeditationStatsTable::count() -> uint32_t
{
- const auto queryRet = db->query("SELECT COUNT(*) FROM '%s';", tableName);
+ const auto queryRet = db->query("SELECT COUNT(*) FROM" str_ ";", tableName);
if (queryRet == nullptr || queryRet->getRowCount() == 0) {
return 0;
}
R image/user/db/meditation_stats_001.sql => products/BellHybrid/services/db/databases/scripts/meditation_stats_001.sql +0 -0
R image/user/db/settings_bell_001.sql => products/BellHybrid/services/db/databases/scripts/settings_bell_001.sql +0 -0
R image/user/db/settings_bell_002.sql => products/BellHybrid/services/db/databases/scripts/settings_bell_002.sql +0 -0
M products/BellHybrid/services/db/tests/CMakeLists.txt => products/BellHybrid/services/db/tests/CMakeLists.txt +1 -1
@@ 6,5 6,5 @@ add_catch2_executable(
LIBS
bell::db::meditation_stats
- USE_FS
+ module-db::test::helpers
)=
\ No newline at end of file
M products/BellHybrid/services/db/tests/MeditationStatisticsTable_tests.cpp => products/BellHybrid/services/db/tests/MeditationStatisticsTable_tests.cpp +8 -34
@@ 4,6 4,7 @@
#include <catch2/catch.hpp>
#include <MeditationStatisticsDB.hpp>
+#include <Helpers.hpp>
#include <filesystem>
#include <iostream>
@@ 22,44 23,17 @@ namespace
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
}
- template <typename Db>
- class TestDatabase
+ std::filesystem::path getScriptsPath()
{
- public:
- explicit TestDatabase(std::filesystem::path name)
- {
- Database::initialize();
-
- if (std::filesystem::exists(name)) {
- REQUIRE(std::filesystem::remove(name));
- }
-
- db = std::make_unique<Db>(name.c_str());
-
- if (not db->isInitialized()) {
- throw std::runtime_error("Could not initialize database");
- }
- }
-
- ~TestDatabase()
- {
- Database::deinitialize();
- }
-
- Db &get()
- {
- return *db;
- }
-
- private:
- std::filesystem::path name;
- std::unique_ptr<Db> db;
- };
+ const std::string path = __FILE__;
+ const auto dir = std::filesystem::path{path.substr(0, path.rfind('/'))};
+ return dir / "../databases/scripts";
+ }
} // namespace
TEST_CASE("Meditation statistics Table - API basic checks")
{
- TestDatabase<MeditationStatisticsDB> db{"meditation_stats.db"};
+ db::tests::DatabaseUnderTest<MeditationStatisticsDB> db{"meditation_stats.db", getScriptsPath()};
const auto timestamp = get_utc_time();
REQUIRE(db.get().table.add({Record{0}, timestamp, std::chrono::minutes{20}}));
@@ 88,7 62,7 @@ TEST_CASE("Meditation statistics Table - API basic checks")
TEST_CASE("Meditation statistics Table - get by days")
{
- TestDatabase<MeditationStatisticsDB> db{"meditation_stats.db"};
+ db::tests::DatabaseUnderTest<MeditationStatisticsDB> db{"meditation_stats.db", getScriptsPath()};
REQUIRE(db.get().table.add({Record{0}, subtract_time(std::chrono::hours{23}), std::chrono::minutes{1}}));
REQUIRE(db.get().table.getByDays(1).size() == 1);
M products/PurePhone/CMakeLists.txt => products/PurePhone/CMakeLists.txt +14 -4
@@ 86,7 86,7 @@ target_link_libraries(PurePhone
)
if (${PROJECT_TARGET} STREQUAL "TARGET_Linux")
- add_dependencies(Pure service_renderer)
+ add_dependencies(PurePhone service_renderer)
endif()
@@ 107,7 107,7 @@ include(BinaryAssetsVersions.cmake)
include(AddVersionJson)
add_directories(
- TARGET user_directories
+ TARGET create_user_directories
PREFIX ${CMAKE_BINARY_DIR}/sysroot/sys/user/audio
DEPENDS user_directories_common
DIRECTORIES music_player
@@ 120,7 120,13 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
PRODUCT PurePhone
SYSROOT sysroot
LUTS Luts.bin
- DEPENDS user_directories assets updater.bin-target ecoboot.bin-target PurePhone-boot.bin PurePhone-version.json-target
+ DEPENDS
+ create_product_databases
+ create_user_directories
+ assets updater.bin-target
+ ecoboot.bin-target
+ PurePhone-boot.bin
+ PurePhone-version.json-target
)
add_version_rt1051_json(PurePhone)
else()
@@ 128,7 134,11 @@ else()
PRODUCT PurePhone
SYSROOT sysroot
LUTS ""
- DEPENDS user_directories assets PurePhone-version.json-target
+ DEPENDS
+ create_product_databases
+ create_user_directories
+ assets
+ PurePhone-version.json-target
)
add_version_linux_json(PurePhone)
endif()
M products/PurePhone/PurePhoneMain.cpp => products/PurePhone/PurePhoneMain.cpp +2 -6
@@ 55,12 55,8 @@
#endif
// modules
-#include <module-db/Databases/CountryCodesDB.hpp>
-#include <module-db/Databases/EventsDB.hpp>
-#include <module-db/Databases/NotificationsDB.hpp>
-#include <module-db/Databases/MultimediaFilesDB.hpp>
-#include <module-db/Interface/AlarmEventRecord.hpp>
-#include <module-db/Interface/CountryCodeRecord.hpp>
+#include "module-db/databases/NotificationsDB.hpp"
+#include <module-db/databases/MultimediaFilesDB.hpp>
#include <module-db/Interface/NotesRecord.hpp>
#include <module-db/Interface/NotificationsRecord.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>
M products/PurePhone/services/db/ServiceDB.cpp => products/PurePhone/services/db/ServiceDB.cpp +12 -19
@@ 3,13 3,11 @@
#include <db/ServiceDB.hpp>
-#include <module-db/Databases/CountryCodesDB.hpp>
-#include <module-db/Databases/EventsDB.hpp>
-#include <module-db/Databases/MultimediaFilesDB.hpp>
-#include <module-db/Databases/NotificationsDB.hpp>
+#include <module-db/databases/EventsDB.hpp>
+#include <module-db/databases/MultimediaFilesDB.hpp>
+#include "module-db/databases/NotificationsDB.hpp"
#include <module-db/Interface/AlarmEventRecord.hpp>
#include <module-db/Interface/CalllogRecord.hpp>
-#include <module-db/Interface/CountryCodeRecord.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>
#include <module-db/Interface/NotesRecord.hpp>
#include <module-db/Interface/NotificationsRecord.hpp>
@@ 35,7 33,6 @@ ServiceDB::~ServiceDB()
contactsDB.reset();
smsDB.reset();
notesDB.reset();
- countryCodesDB.reset();
notificationsDB.reset();
predefinedQuotesDB.reset();
customQuotesDB.reset();
@@ 62,8 59,6 @@ db::Interface *ServiceDB::getInterface(db::Interface::Name interface)
return notesRecordInterface.get();
case db::Interface::Name::Calllog:
return calllogRecordInterface.get();
- case db::Interface::Name::CountryCodes:
- return countryCodeRecordInterface.get();
case db::Interface::Name::Notifications:
return notificationsRecordInterface.get();
case db::Interface::Name::Quotes:
@@ 254,17 249,16 @@ sys::ReturnCodes ServiceDB::InitHandler()
}
// Create databases
- eventsDB = std::make_unique<EventsDB>((purefs::dir::getUserDiskPath() / "events.db").c_str());
- contactsDB = std::make_unique<ContactsDB>((purefs::dir::getUserDiskPath() / "contacts.db").c_str());
- smsDB = std::make_unique<SmsDB>((purefs::dir::getUserDiskPath() / "sms.db").c_str());
- notesDB = std::make_unique<NotesDB>((purefs::dir::getUserDiskPath() / "notes.db").c_str());
- calllogDB = std::make_unique<CalllogDB>((purefs::dir::getUserDiskPath() / "calllog.db").c_str());
- countryCodesDB = std::make_unique<CountryCodesDB>("country-codes.db");
- notificationsDB = std::make_unique<NotificationsDB>((purefs::dir::getUserDiskPath() / "notifications.db").c_str());
- predefinedQuotesDB = std::make_unique<Database>((purefs::dir::getUserDiskPath() / "predefined_quotes.db").c_str());
- customQuotesDB = std::make_unique<Database>((purefs::dir::getUserDiskPath() / "custom_quotes.db").c_str());
+ eventsDB = std::make_unique<EventsDB>((purefs::dir::getDatabasesPath() / "events.db").c_str());
+ contactsDB = std::make_unique<ContactsDB>((purefs::dir::getDatabasesPath() / "contacts.db").c_str());
+ smsDB = std::make_unique<SmsDB>((purefs::dir::getDatabasesPath() / "sms.db").c_str());
+ notesDB = std::make_unique<NotesDB>((purefs::dir::getDatabasesPath() / "notes.db").c_str());
+ calllogDB = std::make_unique<CalllogDB>((purefs::dir::getDatabasesPath() / "calllog.db").c_str());
+ notificationsDB = std::make_unique<NotificationsDB>((purefs::dir::getDatabasesPath() / "notifications.db").c_str());
+ predefinedQuotesDB = std::make_unique<Database>((purefs::dir::getDatabasesPath() / "predefined_quotes.db").c_str());
+ customQuotesDB = std::make_unique<Database>((purefs::dir::getDatabasesPath() / "custom_quotes.db").c_str());
multimediaFilesDB = std::make_unique<db::multimedia_files::MultimediaFilesDB>(
- (purefs::dir::getUserDiskPath() / "multimedia.db").c_str());
+ (purefs::dir::getDatabasesPath() / "multimedia.db").c_str());
// Create record interfaces
alarmEventRecordInterface = std::make_unique<AlarmEventRecordInterface>(eventsDB.get());
@@ 274,7 268,6 @@ sys::ReturnCodes ServiceDB::InitHandler()
smsTemplateRecordInterface = std::make_unique<SMSTemplateRecordInterface>(smsDB.get());
notesRecordInterface = std::make_unique<NotesRecordInterface>(notesDB.get());
calllogRecordInterface = std::make_unique<CalllogRecordInterface>(calllogDB.get(), contactsDB.get());
- countryCodeRecordInterface = std::make_unique<CountryCodeRecordInterface>(countryCodesDB.get());
notificationsRecordInterface =
std::make_unique<NotificationsRecordInterface>(notificationsDB.get(), contactRecordInterface.get());
multimediaFilesRecordInterface =
R image/user/db/alarms_001.sql => products/PurePhone/services/db/databases/scripts/alarms_001.sql +0 -0
R image/user/db/alarms_002.sql => products/PurePhone/services/db/databases/scripts/alarms_002.sql +0 -0
R image/user/db/calllog_001.sql => products/PurePhone/services/db/databases/scripts/calllog_001.sql +0 -0
R image/user/db/calllog_002-devel.sql => products/PurePhone/services/db/databases/scripts/calllog_002-devel.sql +0 -0
R image/user/db/contacts_001.sql => products/PurePhone/services/db/databases/scripts/contacts_001.sql +0 -0
R image/user/db/contacts_002.sql => products/PurePhone/services/db/databases/scripts/contacts_002.sql +0 -0
R image/user/db/contacts_003-devel.sql => products/PurePhone/services/db/databases/scripts/contacts_003-devel.sql +0 -0
R image/user/db/custom_quotes_001.sql => products/PurePhone/services/db/databases/scripts/custom_quotes_001.sql +0 -0
R image/user/db/custom_quotes_002-devel.sql => products/PurePhone/services/db/databases/scripts/custom_quotes_002-devel.sql +0 -0
R image/user/db/notes_001.sql => products/PurePhone/services/db/databases/scripts/notes_001.sql +0 -0
R image/user/db/notes_002-devel.sql => products/PurePhone/services/db/databases/scripts/notes_002-devel.sql +0 -0
R image/user/db/notifications_001.sql => products/PurePhone/services/db/databases/scripts/notifications_001.sql +0 -0
R image/user/db/notifications_002.sql => products/PurePhone/services/db/databases/scripts/notifications_002.sql +0 -0
R image/user/db/predefined_quotes_001.sql => products/PurePhone/services/db/databases/scripts/predefined_quotes_001.sql +0 -0
R image/user/db/predefined_quotes_002-devel.sql => products/PurePhone/services/db/databases/scripts/predefined_quotes_002-devel.sql +0 -0
R image/user/db/predefined_quotes_002.sql => products/PurePhone/services/db/databases/scripts/predefined_quotes_002.sql +0 -0
R image/user/db/settings_v2_001.sql => products/PurePhone/services/db/databases/scripts/settings_v2_001.sql +0 -0
R image/user/db/settings_v2_002-devel.sql => products/PurePhone/services/db/databases/scripts/settings_v2_002-devel.sql +1 -1
@@ 8,7 8,7 @@ INSERT OR REPLACE INTO dictionary_tab (path, value) VALUES
('system/phone_mode', 'dnd');
-- ----------- insert default values -------------------
-INSERT OR IGNORE INTO settings_tab (path, value) VALUES
+INSERT OR REPLACE INTO settings_tab (path, value) VALUES
('system/phone_mode', 'online'),
('gs_time_format', '0'),
('gs_date_format', '1'),
R image/user/db/settings_v2_002.sql => products/PurePhone/services/db/databases/scripts/settings_v2_002.sql +0 -0
R image/user/db/sms_001.sql => products/PurePhone/services/db/databases/scripts/sms_001.sql +0 -0
R image/user/db/sms_002.sql => products/PurePhone/services/db/databases/scripts/sms_002.sql +0 -0
R image/user/db/sms_003.sql => products/PurePhone/services/db/databases/scripts/sms_003.sql +0 -0
R image/user/db/sms_004-devel.sql => products/PurePhone/services/db/databases/scripts/sms_004-devel.sql +0 -0
M products/PurePhone/services/db/include/db/ServiceDB.hpp => products/PurePhone/services/db/include/db/ServiceDB.hpp +0 -5
@@ 7,13 7,11 @@
#include <service-db/ServiceDBCommon.hpp>
class AlarmEventRecordInterface;
-class AlarmsRecordInterface;
class CalllogDB;
class CalllogRecordInterface;
class ContactRecordInterface;
class ContactsDB;
class CountryCodeRecordInterface;
-class CountryCodesDB;
class DatabaseAgent;
class EventsDB;
class NotesDB;
@@ 22,7 20,6 @@ class NotificationsDB;
class NotificationsRecordInterface;
class SMSRecordInterface;
class SMSTemplateRecordInterface;
-class SettingsDB;
class SmsDB;
class ThreadRecordInterface;
@@ 51,7 48,6 @@ class ServiceDB : public ServiceDBCommon
std::unique_ptr<ContactsDB> contactsDB;
std::unique_ptr<NotesDB> notesDB;
std::unique_ptr<CalllogDB> calllogDB;
- std::unique_ptr<CountryCodesDB> countryCodesDB;
std::unique_ptr<NotificationsDB> notificationsDB;
std::unique_ptr<Database> predefinedQuotesDB;
std::unique_ptr<Database> customQuotesDB;
@@ 64,7 60,6 @@ class ServiceDB : public ServiceDBCommon
std::unique_ptr<ContactRecordInterface> contactRecordInterface;
std::unique_ptr<NotesRecordInterface> notesRecordInterface;
std::unique_ptr<CalllogRecordInterface> calllogRecordInterface;
- std::unique_ptr<CountryCodeRecordInterface> countryCodeRecordInterface;
std::unique_ptr<NotificationsRecordInterface> notificationsRecordInterface;
std::unique_ptr<Quotes::QuotesAgent> quotesRecordInterface;
std::unique_ptr<db::multimedia_files::MultimediaFilesRecordInterface> multimediaFilesRecordInterface;
M products/PurePhone/test/test-settings/Database.cpp => products/PurePhone/test/test-settings/Database.cpp +1 -3
@@ 123,9 123,7 @@ std::unique_ptr<QueryResult> stubQuery(const std::string &format, const std::str
return queryResult;
}
-Database::Database(const char *name, bool)
- : dbName(name), queryStatementBuffer{nullptr}, isInitialized_(false),
- initializer(std::make_unique<DatabaseInitializer>(this))
+Database::Database(const char *name, bool) : dbName(name), queryStatementBuffer{nullptr}, isInitialized_(false)
{
isInitialized_ = true;
}
M products/PurePhone/test/test-settings/test-service-db-settings-api.cpp => products/PurePhone/test/test-settings/test-service-db-settings-api.cpp +6 -10
@@ 12,23 12,19 @@
#include <evtmgr/EventManager.hpp>
#include <sys/SystemManager.hpp>
-#include <service-evtmgr/Constants.hpp>
-
#include "test-service-db-settings-testmsgs.hpp"
#include "test-service-db-settings-testservices.hpp"
#include "test-service-db-settings-testapps.hpp"
#include "Database.cpp"
-#include <module-db/Databases/CalllogDB.hpp>
-#include <module-db/Databases/CountryCodesDB.hpp>
-#include <module-db/Databases/EventsDB.hpp>
-#include <module-db/Databases/MultimediaFilesDB.hpp>
-#include <module-db/Databases/NotesDB.hpp>
-#include <module-db/Databases/NotificationsDB.hpp>
-#include <module-db/Databases/SmsDB.hpp>
+#include "module-db/databases/CalllogDB.hpp"
+#include <module-db/databases/EventsDB.hpp>
+#include <module-db/databases/MultimediaFilesDB.hpp>
+#include "module-db/databases/NotesDB.hpp"
+#include "module-db/databases/NotificationsDB.hpp"
+#include "module-db/databases/SmsDB.hpp"
#include <module-db/Interface/AlarmEventRecord.hpp>
#include <module-db/Interface/CalllogRecord.hpp>
-#include <module-db/Interface/CountryCodeRecord.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>
#include <module-db/Interface/NotesRecord.hpp>
#include <module-db/Interface/NotificationsRecord.hpp>
M tools/generate_image.sh => tools/generate_image.sh +1 -1
@@ 96,7 96,7 @@ fi
cd "${SYSROOT}/sys"
#Copy FAT data
-CURRENT_DATA="assets country-codes.db ${LUTS}"
+CURRENT_DATA="assets ${LUTS}"
mmd -i "$PART1" ::/current
mmd -i "$PART1" ::/current/sys
M tools/generate_update_image.sh => tools/generate_update_image.sh +0 -2
@@ 32,7 32,6 @@ function setVars() {
"sysroot/sys/current/assets"
"sysroot/sys/user"
"sysroot/sys/current/${SOURCE_TARGET}-boot.bin"
- "sysroot/sys/current/country-codes.db"
"sysroot/sys/current/Luts.bin"
"version.json"
"ecoboot.bin"
@@ 75,7 74,6 @@ function linkInStageing(){
ln -s ../sysroot/sys/user
ln -s ../sysroot/sys/current/${SOURCE_TARGET}-boot.bin boot.bin
- ln -s ../sysroot/sys/current/country-codes.db
ln -s ../sysroot/sys/current/Luts.bin
ln -s ../ecoboot.bin
ln -s ../updater.bin
A tools/init_databases.py => tools/init_databases.py +95 -0
@@ 0,0 1,95 @@
+#!/usr/bin/python3
+# Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+# import required module
+import os
+import sqlite3
+import argparse
+import logging
+import sys
+
+log = logging.getLogger(__name__)
+logging.basicConfig(format='%(asctime)s [%(levelname)s]: %(message)s', level=logging.INFO)
+
+
+# this helper script creates DBs from SQL schema files
+
+def initialize_database(script_path: os.path, dst_directory: os.path) -> int:
+ file_name = os.path.basename(script_path)
+ connection = None
+
+ db_name = file_name.split("_0")[0]
+ db_name = f"{db_name}.db"
+ dst_db_path = os.path.join(dst_directory, db_name)
+ log.debug(f"Executing {script_path} script into {dst_db_path} database")
+
+ ret = 0
+ try:
+ connection = sqlite3.connect(dst_db_path)
+ with open(script_path) as fp:
+ connection.executescript(fp.read())
+ connection.commit()
+ except OSError as e:
+ log.error(f"System error: {e}")
+ ret = 1
+ except sqlite3.Error as e:
+ log.error(f"[SQLite] {db_name} database error: {e}")
+ ret = 1
+ finally:
+ if connection:
+ connection.close()
+
+ return ret
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description='Create databases from schema scripts')
+ parser.add_argument('--input_path',
+ metavar='schema_path',
+ type=str,
+ help='path to schema scripts',
+ required=True)
+
+ parser.add_argument('--output_path',
+ metavar='db_path',
+ type=str,
+ help='destination path for databases',
+ required=True)
+
+ parser.add_argument('--development',
+ metavar='devel',
+ type=bool,
+ help='with development schema scripts',
+ default=False)
+
+ args = parser.parse_args()
+
+ db_script_files = [
+ os.path.join(args.input_path, file)
+ for file in os.listdir(args.input_path)
+ if os.path.isfile(os.path.join(args.input_path, file)) and ".sql" in file
+ ]
+ db_script_devel = [file for file in db_script_files if "devel" in file]
+ db_script_no_devel = list(set(db_script_files) - set(db_script_devel))
+
+ db_script_devel.sort()
+ db_script_no_devel.sort()
+
+ if not os.path.exists(args.output_path):
+ os.makedirs(args.output_path, exist_ok=True)
+
+ ret = 0
+
+ for script in db_script_no_devel:
+ ret |= initialize_database(script, args.output_path)
+
+ if args.development:
+ for script in db_script_devel:
+ ret |= initialize_database(script, args.output_path)
+
+ return ret
+
+
+if __name__ == "__main__":
+ sys.exit(main())