[broken build] refactor encryption provider db

This commit is contained in:
Scott E. Graves 2024-12-17 10:44:29 -06:00
parent 2017897ad6
commit db0b209ca6
9 changed files with 987 additions and 388 deletions

View File

@ -0,0 +1,34 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_DB_FILE_DB_HPP_
#define REPERTORY_INCLUDE_DB_FILE_DB_HPP_
#include "db/i_file_db.hpp"
namespace repertory {
class app_config;
[[nodiscard]] auto create_file_db(const app_config &cfg)
-> std::unique_ptr<i_file_db>;
} // namespace repertory
#endif // REPERTORY_INCLUDE_DB_FILE_DB_HPP_

View File

@ -0,0 +1,83 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_
#define REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_
#include "types/repertory.hpp"
namespace repertory {
class i_file_db {
INTERFACE_SETUP(i_file_db);
public:
struct file_data final {
std::string api_path;
std::uint64_t file_size{};
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list{};
std::string source_path;
};
public:
[[nodiscard]] virtual auto add_directory(const std::string &api_path,
const std::string &source_path)
-> api_error = 0;
[[nodiscard]] virtual auto add_or_update_file(const file_data &data)
-> api_error = 0;
virtual void clear() = 0;
[[nodiscard]] virtual auto count() const -> std::uint64_t = 0;
[[nodiscard]] virtual auto get_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error = 0;
[[nodiscard]] virtual auto
get_directory_api_path(const std::string &source_path,
std::string &api_path) const -> api_error = 0;
[[nodiscard]] virtual auto
get_directory_source_path(const std::string &api_path,
std::string &source_path) const -> api_error = 0;
[[nodiscard]] virtual auto get_file_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error = 0;
[[nodiscard]] virtual auto get_file_data(const std::string &api_path,
file_data &data) const
-> api_error = 0;
[[nodiscard]] virtual auto
get_file_source_path(const std::string &api_path,
std::string &source_path) const -> api_error = 0;
[[nodiscard]] virtual auto get_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error = 0;
};
} // namespace repertory
#endif // REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_

View File

@ -0,0 +1,65 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_
#define REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_
#include "db/i_file_db.hpp"
namespace repertory {
class app_config;
class rdb_file_db final : public i_file_db {
public:
rdb_file_db(const app_config &cfg);
~rdb_file_db() override;
rdb_file_db(const rdb_file_db &) = delete;
rdb_file_db(rdb_file_db &&) = delete;
auto operator=(const rdb_file_db &) -> rdb_file_db & = delete;
auto operator=(rdb_file_db &&) -> rdb_file_db & = delete;
private:
const app_config &cfg_;
private:
std::unique_ptr<rocksdb::TransactionDB> db_{nullptr};
private:
void create_or_open(bool clear);
[[nodiscard]] auto create_iterator() const
-> std::shared_ptr<rocksdb::Iterator>;
[[nodiscard]] static auto
perform_action(std::string_view function_name,
std::function<rocksdb::Status()> action) -> bool;
[[nodiscard]] auto perform_action(
std::string_view function_name,
std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) -> bool;
public:
void clear() override;
};
} // namespace repertory
#endif // REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_

View File

@ -0,0 +1,86 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_
#define REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_
#include "db/i_file_db.hpp"
#include "utils/db/sqlite/db_common.hpp"
namespace repertory {
class app_config;
class sqlite_file_db final : public i_file_db {
public:
sqlite_file_db(const app_config &cfg);
~sqlite_file_db() override;
sqlite_file_db(const sqlite_file_db &) = delete;
sqlite_file_db(sqlite_file_db &&) = delete;
auto operator=(const sqlite_file_db &) -> sqlite_file_db & = delete;
auto operator=(sqlite_file_db &&) -> sqlite_file_db & = delete;
private:
utils::db::sqlite::db3_t db_;
public:
[[nodiscard]] auto add_directory(const std::string &api_path,
const std::string &source_path)
-> api_error override;
[[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data)
-> api_error override;
void clear() override;
[[nodiscard]] auto count() const -> std::uint64_t override;
[[nodiscard]] auto get_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error override;
[[nodiscard]] auto get_directory_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error override;
[[nodiscard]] auto get_directory_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error override;
[[nodiscard]] auto get_file_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error override;
[[nodiscard]] auto get_file_data(const std::string &api_path,
i_file_db::file_data &data) const
-> api_error override;
[[nodiscard]] auto get_file_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error override;
[[nodiscard]] auto get_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error override;
};
} // namespace repertory
#endif // REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_

View File

@ -23,8 +23,8 @@
#define REPERTORY_INCLUDE_PROVIDERS_ENCRYPT_ENCRYPT_PROVIDER_HPP_
#include "app_config.hpp"
#include "db/i_file_db.hpp"
#include "providers/i_provider.hpp"
#include "utils/db/sqlite/db_common.hpp"
#include "utils/encrypting_reader.hpp"
namespace repertory {
@ -54,7 +54,7 @@ private:
private:
app_config &config_;
utils::db::sqlite::db3_t db_;
std::unique_ptr<i_file_db> db_;
private:
i_file_manager *fm_{nullptr};

View File

@ -0,0 +1,38 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "db/file_db.hpp"
#include "app_config.hpp"
#include "db/impl/rdb_file_db.hpp"
#include "db/impl/sqlite_file_db.hpp"
namespace repertory {
auto create_file_db(const app_config &cfg) -> std::unique_ptr<i_file_db> {
switch (cfg.get_database_type()) {
case database_type::sqlite:
return std::make_unique<sqlite_file_db>(cfg);
default:
return std::make_unique<rdb_file_db>(cfg);
}
}
} // namespace repertory

View File

@ -0,0 +1,141 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "db/impl/rdb_file_db.hpp"
#include "app_config.hpp"
#include "types/startup_exception.hpp"
#include "utils/config.hpp"
#include "utils/error_utils.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
namespace {
[[nodiscard]] auto
create_rocksdb(const repertory::app_config &cfg, const std::string &name,
const std::vector<rocksdb::ColumnFamilyDescriptor> &families,
std::vector<rocksdb::ColumnFamilyHandle *> &handles, bool clear)
-> std::unique_ptr<rocksdb::TransactionDB> {
REPERTORY_USES_FUNCTION_NAME();
auto path = repertory::utils::path::combine(cfg.get_data_directory(), {name});
if (clear &&
not repertory::utils::file::directory{path}.remove_recursively()) {
repertory::utils::error::raise_error(
function_name, "failed to remove " + name + " db|" + path);
}
rocksdb::Options options{};
options.create_if_missing = true;
options.create_missing_column_families = true;
options.db_log_dir = cfg.get_log_directory();
options.keep_log_file_num = 10;
rocksdb::TransactionDB *ptr{};
auto status = rocksdb::TransactionDB::Open(
options, rocksdb::TransactionDBOptions{}, path, families, &handles, &ptr);
if (not status.ok()) {
repertory::utils::error::raise_error(function_name, status.ToString());
throw repertory::startup_exception(status.ToString());
}
return std::unique_ptr<rocksdb::TransactionDB>(ptr);
}
} // namespace
namespace repertory {
rdb_file_db::rdb_file_db(const app_config &cfg) : cfg_(cfg) {
create_or_open(false);
}
rdb_file_db::~rdb_file_db() { db_.reset(); }
void rdb_file_db::create_or_open(bool clear) {
db_.reset();
auto families = std::vector<rocksdb::ColumnFamilyDescriptor>();
families.emplace_back(rocksdb::kDefaultColumnFamilyName,
rocksdb::ColumnFamilyOptions());
auto handles = std::vector<rocksdb::ColumnFamilyHandle *>();
db_ = create_rocksdb(cfg_, "file", families, handles, clear);
}
void rdb_file_db::clear() { create_or_open(true); }
auto rdb_file_db::create_iterator() const
-> std::shared_ptr<rocksdb::Iterator> {
return std::shared_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
}
auto rdb_file_db::perform_action(std::string_view function_name,
std::function<rocksdb::Status()> action)
-> bool {
try {
auto res = action();
if (not res.ok()) {
utils::error::raise_error(function_name, res.ToString());
}
return res.ok();
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex);
}
return false;
}
auto rdb_file_db::perform_action(
std::string_view function_name,
std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) -> bool {
std::unique_ptr<rocksdb::Transaction> txn{
db_->BeginTransaction(rocksdb::WriteOptions{},
rocksdb::TransactionOptions{}),
};
try {
auto res = action(txn.get());
if (res.ok()) {
auto commit_res = txn->Commit();
if (commit_res.ok()) {
return true;
}
utils::error::raise_error(function_name,
"rocksdb commit failed|" + res.ToString());
return false;
}
utils::error::raise_error(function_name,
"rocksdb action failed|" + res.ToString());
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex,
"failed to handle rocksdb action");
}
auto rollback_res = txn->Rollback();
utils::error::raise_error(function_name, "rocksdb rollback failed|" +
rollback_res.ToString());
return false;
}
} // namespace repertory

View File

@ -0,0 +1,297 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "db/impl/sqlite_file_db.hpp"
#include "app_config.hpp"
#include "utils/config.hpp"
#include "utils/db/sqlite/db_common.hpp"
#include "utils/db/sqlite/db_delete.hpp"
#include "utils/db/sqlite/db_insert.hpp"
#include "utils/db/sqlite/db_select.hpp"
#include "utils/db/sqlite/db_update.hpp"
#include "utils/error_utils.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
namespace {
const std::string file_table = "file";
const std::map<std::string, std::string> sql_create_tables = {
{
{file_table},
{"CREATE TABLE IF NOT EXISTS " + file_table +
"("
"source_path TEXT PRIMARY KEY ASC, "
"api_path TEXT UNIQUE NOT NULL, "
"iv TEXT, "
"directory INTEGER NOT NULL, "
"size INTEGER"
");"},
},
};
} // namespace
namespace repertory {
sqlite_file_db::sqlite_file_db(const app_config &cfg) {
db_ = utils::db::sqlite::create_db(
utils::path::combine(cfg.get_data_directory(), {"file.db"}),
sql_create_tables);
}
sqlite_file_db::~sqlite_file_db() { db_.reset(); }
auto sqlite_file_db::add_directory(const std::string &api_path,
const std::string &source_path)
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto result = utils::db::sqlite::db_insert{*db_, file_table}
.column_value("api_path", api_path)
.column_value("directory", 1)
.column_value("source_path", source_path)
.go();
if (result.ok()) {
return api_error::success;
}
utils::error::raise_api_path_error(
function_name, api_path,
fmt::format("failed to add directory|{}", result.get_error_str()));
return api_error::error;
}
auto sqlite_file_db::add_or_update_file(const i_file_db::file_data &data)
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto result =
utils::db::sqlite::db_insert{*db_, file_table}
.or_replace()
.column_value("api_path", data.api_path)
.column_value("directory", 0)
.column_value("iv", json(data.iv_list).dump())
.column_value("size", static_cast<std::int64_t>(data.file_size))
.column_value("source_path", data.source_path)
.go();
if (result.ok()) {
return api_error::success;
}
utils::error::raise_api_path_error(
function_name, data.api_path,
fmt::format("failed to add file|{}", result.get_error_str()));
return api_error::error;
}
void sqlite_file_db::clear() {
REPERTORY_USES_FUNCTION_NAME();
auto result = utils::db::sqlite::db_delete{*db_, file_table}.go();
if (not result.ok()) {
utils::error::raise_error(function_name,
fmt::format("failed to clear file table|{}",
std::to_string(result.get_error())));
}
}
auto sqlite_file_db::count() const -> std::uint64_t {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.count("api_path", "count")
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
return static_cast<std::uint64_t>(
row->get_column("count").get_value<std::int64_t>());
}
return 0U;
}
auto sqlite_file_db::get_api_path(const std::string &source_path,
std::string &api_path) const -> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(source_path)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path = row->get_column("api_path").get_value<std::string>();
return api_error::success;
}
return api_error::item_not_found;
}
auto sqlite_file_db::get_directory_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(source_path)
.and_()
.where("directory")
.equals(1)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path = row->get_column("api_path").get_value<std::string>();
return api_error::success;
}
return api_error::directory_not_found;
}
auto sqlite_file_db::get_directory_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(1)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
source_path = row->get_column("source_path").get_value<std::string>();
return api_error::success;
}
return api_error::directory_not_found;
}
auto sqlite_file_db::get_file_api_path(const std::string &source_path,
std::string &api_path) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(source_path)
.and_()
.where("directory")
.equals(0)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path = row->get_column("api_path").get_value<std::string>();
return api_error::success;
}
return api_error::item_not_found;
}
auto sqlite_file_db::get_file_data(const std::string &api_path,
i_file_db::file_data &data) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("iv")
.column("size")
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
data.api_path = api_path;
data.file_size = static_cast<std::uint64_t>(
row->get_column("size").get_value<std::int64_t>());
data.source_path = row->get_column("source_path").get_value<std::string>();
auto str_data = row->get_column("iv").get_value<std::string>();
if (not str_data.empty()) {
data.iv_list =
json::parse(str_data)
.get<std::vector<
std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>>();
}
return api_error::success;
}
return api_error::item_not_found;
}
auto sqlite_file_db::get_file_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
source_path = row->get_column("source_path").get_value<std::string>();
return api_error::success;
}
return api_error::item_not_found;
}
auto sqlite_file_db::get_source_path(const std::string &api_path,
std::string &source_path) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
source_path = row->get_column("source_path").get_value<std::string>();
return api_error::success;
}
return api_error::item_not_found;
}
} // namespace repertory

View File

@ -21,6 +21,7 @@
*/
#include "providers/encrypt/encrypt_provider.hpp"
#include "db/file_db.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "types/repertory.hpp"
@ -38,18 +39,6 @@
namespace {
const std::string file_table = "file";
const std::map<std::string, std::string> sql_create_tables = {
{
{file_table},
{"CREATE TABLE IF NOT EXISTS " + file_table +
"("
"source_path TEXT PRIMARY KEY ASC, "
"api_path TEXT NOT NULL, "
"data TEXT, "
"directory INTEGER NOT NULL"
");"},
},
};
} // namespace
namespace repertory {
@ -172,18 +161,7 @@ auto encrypt_provider::get_api_path_from_source(const std::string &source_path,
REPERTORY_USES_FUNCTION_NAME();
try {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(source_path)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path = row->get_column("api_path").get_value<std::string>();
return api_error::success;
}
return api_error::item_not_found;
return db_->get_api_path(source_path, api_path);
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, source_path,
"failed to get api path from source path");
@ -231,61 +209,37 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
for (const auto &dir_entry :
utils::file::directory{source_path}.get_items()) {
try {
std::string current_api_path{};
std::string current_api_path;
if (dir_entry->is_directory_item()) {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(dir_entry->get_path())
.and_()
.where("directory")
.equals(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
current_api_path =
row->get_column("api_path").get_value<std::string>();
auto result = db_->get_directory_api_path(dir_entry->get_path(),
current_api_path);
if (result != api_error::success &&
result != api_error::directory_not_found) {
// TODO raise error
continue;
}
if (current_api_path.empty()) {
if (result == api_error::directory_not_found) {
process_directory_entry(*dir_entry.get(), cfg,
current_api_path);
result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(dir_entry->get_path())
.and_()
.where("directory")
.equals(1)
.go();
row.reset();
if (not(result.get_row(row) && row.has_value())) {
result = get_directory_api_path(dir_entry->get_path(),
current_api_path);
if (result != api_error::success &&
result != api_error::directory_not_found) {
// TODO raise error
continue;
}
current_api_path =
row->get_column("api_path").get_value<std::string>();
}
} else {
std::string api_path_data{};
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.column("data")
.where("source_path")
.equals(dir_entry->get_path())
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path_data =
row->get_column("data").get_value<std::string>();
current_api_path =
row->get_column("api_path").get_value<std::string>();
auto result = db_->get_file_api_path(dir_entry->get_path(),
current_api_path);
if (result != api_error::success &&
result != api_error::item_not_found) {
// TODO raise error
continue;
}
if (api_path_data.empty() &&
if (result == api_error::item_not_found &&
not process_directory_entry(*dir_entry.get(), cfg,
current_api_path)) {
continue;
@ -356,22 +310,13 @@ auto encrypt_provider::get_file(const std::string &api_path,
return api_error::directory_exists;
}
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
std::string source_path;
auto result = db_->get_file_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
file = create_api_file(
api_path, false,
row->get_column("source_path").get_value<std::string>());
file = create_api_file(api_path, false, source_path);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
@ -412,19 +357,11 @@ auto encrypt_provider::get_file_size(const std::string &api_path,
REPERTORY_USES_FUNCTION_NAME();
try {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
std::string source_path;
auto result = db_->get_file_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
file_size = utils::encryption::encrypting_reader::calculate_encrypted_size(
source_path);
@ -441,60 +378,27 @@ auto encrypt_provider::get_filesystem_item(const std::string &api_path,
bool directory,
filesystem_item &fsi) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(directory ? 1 : 0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
return directory ? api_error::directory_not_found
: api_error::item_not_found;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
std::string source_path;
if (directory) {
result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(source_path)
.and_()
.where("directory")
.equals(1)
.go();
row.reset();
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
auto result = db_->get_directory_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
auto db_api_path = row->get_column("api_path").get_value<std::string>();
fsi.api_parent = utils::path::get_parent_api_path(db_api_path);
fsi.api_path = db_api_path;
fsi.api_parent = utils::path::get_parent_api_path(api_path);
fsi.api_path = api_path;
fsi.directory = true;
fsi.size = 0U;
fsi.source_path = source_path;
return api_error::success;
}
result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.column("data")
.where("source_path")
.equals(source_path)
.and_()
.where("directory")
.equals(0)
.go();
row.reset();
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
auto result = db_->get_file_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
fsi.api_path = row->get_column("api_path").get_value<std::string>();
fsi.api_path = api_path;
fsi.api_parent = utils::path::get_parent_api_path(fsi.api_path);
fsi.directory = false;
fsi.size = utils::encryption::encrypting_reader::calculate_encrypted_size(
@ -564,26 +468,20 @@ auto encrypt_provider::get_item_meta(const std::string &api_path,
REPERTORY_USES_FUNCTION_NAME();
try {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
std::string source_path;
auto result = db_->get_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
bool is_dir{};
result = is_directory(api_path, is_dir);
if (result != api_error::success) {
return result;
}
auto file = create_api_file(api_path, exists, source_path);
create_item_meta(meta, exists, file);
auto file = create_api_file(api_path, is_dir, source_path);
create_item_meta(meta, is_dir, file);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
@ -613,14 +511,13 @@ auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
}
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.count("api_path", "count")
.go();
REPERTORY_USES_FUNCTION_NAME();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
return static_cast<std::uint64_t>(
row->get_column("count").get_value<std::int64_t>());
try {
return db_->count();
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex,
"failed to get total item count");
}
return 0U;
@ -635,50 +532,44 @@ auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
auto encrypt_provider::is_directory(const std::string &api_path,
bool &exists) const -> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
exists = false;
REPERTORY_USES_FUNCTION_NAME();
try {
std::string source_path;
auto result = db_->get_directory_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
exists = utils::file::directory{source_path}.exists();
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed determin if api path is directory");
}
exists =
utils::file::directory{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success;
return api_error::error;
}
auto encrypt_provider::is_file(const std::string &api_path, bool &exists) const
-> api_error {
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
exists = false;
REPERTORY_USES_FUNCTION_NAME();
try {
std::string source_path;
auto result = db_->get_file_source_path(api_path, source_path);
if (result != api_error::success) {
return result;
}
exists = utils::file::file{source_path}.exists();
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed determin if api path is directory");
}
exists =
utils::file::file{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success;
return api_error::error;
}
auto encrypt_provider::is_file_writeable(const std::string & /*api_path*/) const
@ -696,148 +587,133 @@ auto encrypt_provider::is_online() const -> bool {
auto encrypt_provider::process_directory_entry(
const utils::file::i_fs_item &dir_entry, const encrypt_config &cfg,
std::string &api_path) const -> bool {
const auto add_directory = [this,
&cfg](std::string_view dir_path) -> std::string {
auto encrypted_parts = utils::string::split(
utils::path::create_api_path(dir_path), '/', false);
REPERTORY_USES_FUNCTION_NAME();
for (std::size_t part_idx = 1U; part_idx < encrypted_parts.size();
++part_idx) {
data_buffer encrypted_data;
utils::encryption::encrypt_data(
cfg.encryption_token,
reinterpret_cast<const unsigned char *>(
encrypted_parts.at(part_idx).c_str()),
strnlen(encrypted_parts.at(part_idx).c_str(),
encrypted_parts.at(part_idx).size()),
encrypted_data);
encrypted_parts[part_idx] =
utils::collection::to_hex_string(encrypted_data);
}
try {
const auto do_add_directory =
[this, &cfg](std::string_view dir_path) -> std::string {
auto encrypted_parts = utils::string::split(
utils::path::create_api_path(dir_path), '/', false);
std::size_t current_idx{1U};
std::string current_encrypted_path{};
auto current_source_path{cfg.path};
for (const auto &part : utils::path::get_parts(dir_path)) {
current_source_path = utils::path::combine(current_source_path, {part});
std::string current_api_path{};
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(current_source_path)
.and_()
.where("directory")
.equals(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
current_api_path = row->get_column("api_path").get_value<std::string>();
for (std::size_t part_idx = 1U; part_idx < encrypted_parts.size();
++part_idx) {
data_buffer encrypted_data;
utils::encryption::encrypt_data(
cfg.encryption_token,
reinterpret_cast<const unsigned char *>(
encrypted_parts.at(part_idx).c_str()),
strnlen(encrypted_parts.at(part_idx).c_str(),
encrypted_parts.at(part_idx).size()),
encrypted_data);
encrypted_parts[part_idx] =
utils::collection::to_hex_string(encrypted_data);
}
if (current_api_path.empty()) {
current_api_path = utils::path::create_api_path(
current_encrypted_path + '/' + encrypted_parts.at(current_idx));
std::size_t current_idx{1U};
std::string current_encrypted_path{};
auto current_source_path{cfg.path};
for (const auto &part : utils::path::get_parts(dir_path)) {
current_source_path = utils::path::combine(current_source_path, {part});
std::string current_api_path{};
auto result =
db_->get_directory_api_path(current_source_path, current_api_path);
if (result == api_error::directory_not_found) {
current_api_path = utils::path::create_api_path(
current_encrypted_path + '/' + encrypted_parts.at(current_idx));
result = db_->add_directory(current_api_path, current_source_path);
if (result != api_error::success) {
std::runtime_error(
fmt::format("failed to get directory api path|{}",
api_error_to_string(result)));
}
event_system::instance().raise<filesystem_item_added>(
current_api_path,
utils::path::get_parent_api_path(current_api_path), true);
} else {
if (result != api_error::success) {
std::runtime_error(
fmt::format("failed to get directory api path|{}",
api_error_to_string(result)));
}
encrypted_parts[current_idx] =
utils::string::split(current_api_path, '/', false)[current_idx];
}
current_encrypted_path = utils::path::create_api_path(
current_encrypted_path + '/' + encrypted_parts.at(current_idx++));
}
return current_encrypted_path;
};
if (dir_entry.is_directory_item()) {
api_path = do_add_directory(
utils::path::get_relative_path(dir_entry.get_path(), cfg.path));
return false;
}
if (dir_entry.is_file_item() && not dir_entry.is_symlink()) {
auto relative_path =
utils::path::get_relative_path(dir_entry.get_path(), cfg.path);
i_file_db::file_data data;
auto file_res = db_->get_file_data(dir_entry.get_path(), data);
if (file_res != api_error::success &&
file_res != api_error::item_not_found) {
// TODO raise error
return false;
}
std::string api_parent{};
auto parent_res = db_->get_directory_api_path(
utils::path::get_parent_path(dir_entry.get_path()), api_parent);
if (parent_res != api_error::success &&
parent_res != api_error::directory_not_found) {
// TODO raise error
return false;
}
if (parent_res == api_error::directory_not_found) {
api_parent =
do_add_directory(utils::path::get_parent_path(relative_path));
}
if (file_res == api_error::item_not_found) {
stop_type stop_requested{false};
utils::encryption::encrypting_reader reader(
utils::path::strip_to_file_name(relative_path),
dir_entry.get_path(), stop_requested, cfg.encryption_token,
utils::path::get_parent_path(relative_path));
api_path = utils::path::create_api_path(
api_parent + "/" + reader.get_encrypted_file_name());
file_res = db_->add_or_update_file(
i_file_db::file_data{
api_path,
dynamic_cast<const utils::file::i_file *>(&dir_entry)
->size()
.value_or(0U),
reader.get_iv_list(),
},
dir_entry.get_path());
if (file_res != api_error::success) {
// TODO raise error
return false;
}
// TODO handle error
auto ins_res = utils::db::sqlite::db_insert{*db_, file_table}
.column_value("api_path", current_api_path)
.column_value("data", "")
.column_value("directory", 1)
.column_value("source_path", current_source_path)
.go();
event_system::instance().raise<filesystem_item_added>(
current_api_path,
utils::path::get_parent_api_path(current_api_path), true);
} else {
encrypted_parts[current_idx] =
utils::string::split(current_api_path, '/', false)[current_idx];
api_path, api_parent, false);
}
current_encrypted_path = utils::path::create_api_path(
current_encrypted_path + '/' + encrypted_parts.at(current_idx++));
return true;
}
return current_encrypted_path;
};
if (dir_entry.is_directory_item()) {
api_path = add_directory(
utils::path::get_relative_path(dir_entry.get_path(), cfg.path));
return false;
}
if (dir_entry.is_file_item() && not dir_entry.is_symlink()) {
auto relative_path =
utils::path::get_relative_path(dir_entry.get_path(), cfg.path);
std::string api_path_data{};
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.column("data")
.where("source_path")
.equals(dir_entry.get_path())
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {
api_path_data = row->get_column("data").get_value<std::string>();
api_path = row->get_column("api_path").get_value<std::string>();
}
std::string api_parent{};
result = utils::db::sqlite::db_select{*db_, file_table}
.column("api_path")
.where("source_path")
.equals(utils::path::get_parent_path(dir_entry.get_path()))
.and_()
.where("directory")
.equals(1)
.go();
row.reset();
if (result.get_row(row) && row.has_value()) {
api_parent = row->get_column("api_path").get_value<std::string>();
}
if (api_parent.empty()) {
api_parent = add_directory(utils::path::get_parent_path(relative_path));
}
if (api_path.empty()) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader(
utils::path::strip_to_file_name(relative_path), dir_entry.get_path(),
stop_requested, cfg.encryption_token,
utils::path::get_parent_path(relative_path));
api_path = utils::path::create_api_path(api_parent + "/" +
reader.get_encrypted_file_name());
auto iv_list = reader.get_iv_list();
json data = {
{"iv_list", iv_list},
{
"original_file_size",
(dynamic_cast<const utils::file::i_file *>(&dir_entry)
->size()
.value_or(0U)),
},
};
// TODO handle error
auto ins_res = utils::db::sqlite::db_insert{*db_, file_table}
.column_value("api_path", api_path)
.column_value("data", data.dump())
.column_value("directory", 0)
.column_value("source_path", dir_entry.get_path())
.go();
event_system::instance().raise<filesystem_item_added>(api_path,
api_parent, false);
}
return true;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, dir_entry.get_path(),
"failed to process directory entry");
}
return false;
@ -849,84 +725,57 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
stop_type &stop_requested) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto result = utils::db::sqlite::db_select{*db_, file_table}
.column("data")
.column("source_path")
.where("api_path")
.equals(api_path)
.and_()
.where("directory")
.equals(0)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
i_file_db::file_data file_data{};
auto result = db_->get_file_data(api_path, file_data);
if (result != api_error::success) {
return result;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
if (source_path.empty()) {
return api_error::item_not_found;
}
auto file_data = row->get_column("data").get_value_as_json();
auto opt_size = utils::file::file{source_path}.size();
auto opt_size = utils::file::file{data.source_path}.size();
if (not opt_size.has_value()) {
return api_error::os_error;
}
auto file_size{opt_size.value()};
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list{};
auto cfg = config_.get_encrypt_config();
unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_);
if (file_data.at("original_file_size").get<std::uint64_t>() != file_size) {
auto relative_path = utils::path::get_relative_path(source_path, cfg.path);
if (file_data.file_size != file_size) {
auto relative_path =
utils::path::get_relative_path(file_data.source_path, cfg.path);
auto info = std::make_shared<reader_info>();
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
relative_path, source_path, stop_requested, cfg.encryption_token,
utils::path::get_parent_path(relative_path));
reader_lookup_[source_path] = info;
iv_list = info->reader->get_iv_list();
relative_path, file_data.source_path, stop_requested,
cfg.encryption_token, utils::path::get_parent_path(relative_path));
reader_lookup_[file_data.source_path] = info;
file_data.file_size = file_size;
file_data.iv_list = info->reader->get_iv_list();
file_data["original_file_size"] = file_size;
file_data["iv_list"] = iv_list;
auto ins_res = utils::db::sqlite::db_insert{*db_, file_table}
.or_replace()
.column_value("data", file_data.dump())
.column_value("source_path", source_path)
.go();
if (not ins_res.ok()) {
utils::error::raise_error(function_name, ins_res.get_error(), source_path,
"failed to update meta db");
return api_error::error;
}
} else {
iv_list =
file_data["iv_list"]
.get<std::vector<
std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>>();
if (reader_lookup_.find(source_path) == reader_lookup_.end()) {
auto info = std::make_shared<reader_info>();
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
api_path, source_path, stop_requested, cfg.encryption_token,
std::move(iv_list));
reader_lookup_[source_path] = info;
result = db_->add_or_update_file(file_data);
file_data.iv_list.clear();
if (result != api_error::success) {
utils::error::raise_error(function_name, result, file_data.source_path,
"failed to update file");
return result;
}
} else if (reader_lookup_.find(file_data.source_path) ==
reader_lookup_.end()) {
auto info = std::make_shared<reader_info>();
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
api_path, file_data.source_path, stop_requested, cfg.encryption_token,
std::move(file_data.iv_list));
reader_lookup_[file_data.source_path] = info;
}
if (file_size == 0U || size == 0U) {
return api_error::success;
}
auto info = reader_lookup_.at(source_path);
auto info = reader_lookup_.at(file_data.source_path);
info->last_access_time = std::chrono::system_clock::now();
reader_lookup_lock.unlock();
@ -978,6 +827,8 @@ void encrypt_provider::remove_deleted_files(const stop_type &stop_requested) {
.column("source_path")
.where("source_path")
.equals(source_path)
.op()
.limit(1)
.go();
removed_list.emplace_back(removed_item{
api_path,
@ -1003,6 +854,8 @@ void encrypt_provider::remove_deleted_files(const stop_type &stop_requested) {
.and_()
.where("directory")
.equals(0)
.op()
.limit(1)
.go();
event_system::instance().raise<file_removed_externally>(item.api_path,
item.source_path);
@ -1024,6 +877,8 @@ void encrypt_provider::remove_deleted_files(const stop_type &stop_requested) {
.and_()
.where("directory")
.equals(1)
.op()
.limit(1)
.go();
event_system::instance().raise<directory_removed_externally>(
item.api_path, item.source_path);
@ -1038,9 +893,7 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
return false;
}
db_ = utils::db::sqlite::create_db(
utils::path::combine(config_.get_data_directory(), {"provider_meta.db"}),
sql_create_tables);
db_ = create_file_db(config_);
auto cfg = config_.get_encrypt_config();
auto cfg_path = utils::path::absolute(cfg.path);
@ -1052,6 +905,8 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
.and_()
.where("directory")
.equals(1)
.op()
.limit(1)
.go();
std::optional<utils::db::sqlite::db_result::row> row;
if (result.get_row(row) && row.has_value()) {