first implementation of database objects

This commit is contained in:
Andrei Yankovich 2024-01-11 23:24:15 +01:00
parent a9416ebe3a
commit 024642dfc6
9 changed files with 129 additions and 522 deletions

@ -1,8 +1,5 @@
<RCC>
<qresource prefix="/">
<file>src/sql/YourTimeDB_1.sql</file>
<file>src/sql/YourTimeDB_2.sql</file>
<file>src/sql/YourTimeDB_3.sql</file>
<file>src/sql/SecretDB_1.sql</file>
</qresource>
<qresource prefix="/YourTime/languages"/>
</RCC>

@ -1,58 +0,0 @@
//#
//# Copyright (C) 2023-2024 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "image.h"
namespace QASecret {
Image::Image() {}
const QString &Image::getId() const {
return _id;
}
void Image::setId(const QString &id) {
_id = id;
}
const QByteArray &Image::getImage() const {
return _image;
}
void Image::setImage(const QByteArray &source) {
_image = source;
}
QH::PKG::DBObject* Image::createDBObject() const {
return new Image();
}
bool Image::fromSqlRecord(const QSqlRecord& q) {
_id = q.value("id").toString();
_image = q.value("data").toByteArray();
return true;
}
QString Image::table() const {
return "Images";
}
QH::PKG::DBVariantMap Image::variantMap() const {
return {
{"id", {_id, QH::PKG::MemberType::PrimaryKey}},
{"data", {_image, QH::PKG::MemberType::InsertUpdate}}
};
}
QString Image::primaryKey() const {
return "id";
}
QVariant Image::primaryValue() const {
return _id;
}
}

@ -0,0 +1,77 @@
//#
//# Copyright (C) 2023-2024 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "record.h"
#include <QCryptographicHash>
namespace QASecret {
Record::Record() {}
QH::PKG::DBObject* Record::createDBObject() const {
return new Record();
}
bool Record::fromSqlRecord(const QSqlRecord& q) {
_hash = q.value("hash").toByteArray();
_data = q.value("data").toByteArray();
_alias = q.value("alias").toString();
return true;
}
QString Record::table() const {
return "Records";
}
QH::PKG::DBVariantMap Record::variantMap() const {
return {
{"hash", {_hash, QH::PKG::MemberType::Unique}},
{"alias", {_alias, static_cast<QH::PKG::MemberType>(static_cast<int>(QH::PKG::MemberType::InsertUpdate) |
static_cast<int>(QH::PKG::MemberType::Unique))}},
{"data", {_data, QH::PKG::MemberType::Insert}}
};
}
QString Record::primaryKey() const {
return "hash";
}
QVariant Record::primaryValue() const {
return _hash;
}
const QString &QASecret::Record::getAlias() const {
return _alias;
}
void Record::setAlias(const QString &alias) {
_alias = alias;
}
const QByteArray &Record::getHash() const {
return _hash;
}
void Record::setHash(const QByteArray &source) {
_hash = source;
}
const QByteArray &Record::getData() const {
return _data;
}
void Record::setData(const QByteArray &newData) {
_data = newData;
setHash(QCryptographicHash::hash(_data, QCryptographicHash::Sha256));
}
}

@ -6,11 +6,11 @@
//#
#ifndef IMAGE_H
#define IMAGE_H
#ifndef RECORD_H
#define RECORD_H
#include "dbobject.h"
#include <SecretDB/iimage.h>
#include <SecretDB/irecord.h>
#include <QByteArray>
#include <QString>
@ -18,19 +18,20 @@
namespace QASecret {
/**
* @brief The Image class
* @brief The Record class
*/
class Image : public QH::PKG::DBObject, public iImage
class Record : public QH::PKG::DBObject, public iRecord
{
public:
Image();
Record();
// iImage interface
const QString &getId() const override;
void setId(const QString &id) override;
const QByteArray &getImage() const override;
void setImage(const QByteArray &source) override;
// iRecord interface
const QString &getAlias() const override;
void setAlias(const QString &alias) override;
const QByteArray &getHash() const override;
void setHash(const QByteArray &source) override;
const QByteArray &getData() const override;
void setData(const QByteArray &newData) override;
// DBObject interface
QH::PKG::DBObject* createDBObject() const override;
@ -42,8 +43,9 @@ public:
QVariant primaryValue() const override;
private:
QString _id;
QByteArray _image;
QString _alias;
QByteArray _hash;
QByteArray _data;
};
}
#endif // IMAGE_H
#endif // RECORD_H

@ -5,253 +5,37 @@
//# of this license document, but changing it is not allowed.
//#
#include "botdatabase.h"
#include "image.h"
#include "processedid.h"
#include "secretdatabase.h"
#include <QCryptographicHash>
#include <dbobjectsrequest.h>
#include <menuitem.h>
#include <menuitem_v0.h>
#include <order.h>
#include <role.h>
#include <sqldb.h>
#include <user.h>
namespace QASecret {
BotDataBase::BotDataBase() {
SecretDataBase::SecretDataBase() {
addDBPatch({
0,
1,
[](const QH::iObjectProvider* database) -> bool {
return database->doSql(":/src/sql/YourTimeDB_1.sql");
return database->doSql(":/src/sql/SecretDB_1.sql");
}
});
addDBPatch({
1,
2,
[](const QH::iObjectProvider* database) -> bool {
return database->doSql(":/src/sql/YourTimeDB_2.sql");
}
});
addDBPatch({
2,
3,
[this](QH::iObjectProvider* database) -> bool {
if (!database->doSql(":/src/sql/YourTimeDB_3.sql")) {
return false;
}
QH::PKG::DBObjectsRequest<MenuItem_v0>
request("MenuV0");
auto&& oldMenu = database->getObject(request);
for (const auto &oldMenuItem: oldMenu->data()) {
auto&& menuItem = getMenuById(oldMenuItem->getId(), true);
menuItem->setCategory(oldMenuItem->category());
menuItem->setName(oldMenuItem->getName());
menuItem->setDescription(oldMenuItem->getDescription());
menuItem->setPrice(oldMenuItem->getPrice());
menuItem->setTranslations(oldMenuItem->getTranslations());
const auto& image = oldMenuItem->getImage();
if (image.size()) {
auto&& imageId = QCryptographicHash::hash(image,
QCryptographicHash::Sha256).
toBase64(QByteArray::Base64UrlEncoding);
auto&& imageObj = getImageById(imageId, true);
imageObj->setImage(image);
saveImage(imageObj);
menuItem->setImage(imageId);
} else if (oldMenuItem->getImageSource().size()) {
menuItem->setImage(oldMenuItem->getImageSource());
}
saveMenuItem(menuItem);
}
return database->doQuery("DROP TABLE MenuV0");
}
});
}
QSet<unsigned long long> BotDataBase::getProcessedIds() {
QSet<unsigned long long> result;
QH::PKG::DBObjectsRequest<ProcessedId>
request("ProcessedIds");
auto&& responce = db()->getObject(request);
if (!responce)
return result;
auto&& resp = responce->data();
for (const auto& val: resp) {
result.insert(val->getId());
}
return result;
}
void BotDataBase::addProcessedId(unsigned long long id) {
auto&& idObj = QSharedPointer<ProcessedId>::create();
idObj->setId(id);
db()->insertObject(idObj);
}
void BotDataBase::removeProcessedId(unsigned long long id) {
auto&& idObj = QSharedPointer<ProcessedId>::create();
idObj->setId(id);
db()->deleteObject(idObj);
QSharedPointer<iRecord>
SecretDataBase::getRecordByAlias(const QString &alias, bool ifNotExistsCreate) {
}
void BotDataBase::setProcessedIds(const QSet<unsigned long long> &ids) {
auto request = QSharedPointer<QH::PKG::DBObjectsRequest<ProcessedId>>::create(
"ProcessedIds");
db()->deleteObject(request);
for (const auto& id : ids) {
addProcessedId(id);
}
}
QSharedPointer<iUser> BotDataBase::getUserById(unsigned long long id, bool ifNotExistsCreate) {
return getById<User>(id, &User::setId, ifNotExistsCreate);
}
QList<QSharedPointer<iUser>> BotDataBase::getAllUsers(iRole::RoleName roleName) {
QString condition;
if (roleName != iRole::All) {
condition = QString("role = %0").arg(roleName);
condition = QString("id IN ( SELECT userId FROM Roles WHERE %0 )").arg(condition);
}
auto&& data = getAll<User>("Users", condition);
return {data.begin(), data.end()};
}
void BotDataBase::saveUser(const QSharedPointer<iUser>& user) {
saveObj(user.dynamicCast<User>());
}
void BotDataBase::removeUser(unsigned long long id) {
deleteById<User>(id, &User::setId);
}
QSharedPointer<iRole> BotDataBase::getRoleByUserId(unsigned long long userId, bool ifNotExistsCreate) {
return getById<Role>(userId, &Role::setUserId, ifNotExistsCreate);
}
void BotDataBase::saveRole(const QSharedPointer<iRole>& role) {
saveObj(role.dynamicCast<Role>());
}
void BotDataBase::removeRole(unsigned long long userId) {
deleteById<Role>(userId, &Role::setUserId);
}
QSharedPointer<iMenuItem> BotDataBase::getMenuById(int id, bool ifNotExistsCreate) {
return getById<MenuItem>(id, &MenuItem::setId, ifNotExistsCreate);
}
QList<QSharedPointer<iMenuItem>> BotDataBase::getAllMenuItems() {
auto&& data = getAll<MenuItem>("Menu");
return {data.begin(), data.end()};
}
void BotDataBase::saveMenuItem(const QSharedPointer<iMenuItem>& menuItem) {
saveObj(menuItem.dynamicCast<MenuItem>());
}
unsigned int BotDataBase::insertMenuItem(const QSharedPointer<iMenuItem> &menuItem) {
auto&& resultId = QSharedPointer<unsigned int>::create();
insertObj(menuItem.dynamicCast<MenuItem>(), resultId.toWeakRef());
return *resultId;
}
void BotDataBase::removeMenuItem(int id) {
deleteById<MenuItem>(id, &MenuItem::setId);
}
void BotDataBase::clearMenuTable() const {
db()->doQuery("DELETE FROM Menu", {}, true);
}
QSharedPointer<iMenuItem> BotDataBase::makeMenuItem() {
if (auto&& menuItem = QSharedPointer<MenuItem>::create()) {
menuItem->setId(insertMenuItem(menuItem));
return std::move(menuItem);
}
return nullptr;
}
QSharedPointer<iOrder> BotDataBase::getOrderById(int id, bool ifNotExistsCreate) {
return getById<Order>(id, &Order::setId, ifNotExistsCreate);
}
QList<QSharedPointer<iOrder>> BotDataBase::getAllOrders(iOrder::State state) {
QString condition;
if (state != iOrder::All) {
condition = QString("state = %0").arg(state);
}
auto&& data = getAll<Order>("Orders", condition);
return {data.begin(), data.end()};
}
void BotDataBase::saveOrder(const QSharedPointer<iOrder>& order) {
saveObj(order.dynamicCast<Order>());
}
unsigned int BotDataBase::insertOrder(const QSharedPointer<iOrder> &order) {
auto&& resultId = QSharedPointer<unsigned int>::create();
insertObj(order.dynamicCast<Order>(), resultId);
return *resultId;
}
QSharedPointer<iOrder> BotDataBase::makeOrder() {
if (auto&& newOrder = QSharedPointer<Order>::create()) {
newOrder->setId(insertOrder(newOrder));
return std::move(newOrder);
}
return nullptr;
}
void BotDataBase::removeOrder(int id) {
deleteById<Order>(id, &Order::setId);
}
QList<QSharedPointer<iImage> > BotDataBase::getAllImages() {
auto&& data = getAll<Image>("Images", "");
return {data.begin(), data.end()};
}
QSharedPointer<iImage> BotDataBase::getImageById(const QString &id, bool ifNotExistsCreate) {
return getById<Image>(id, &Image::setId, ifNotExistsCreate);
}
void BotDataBase::saveImage(const QSharedPointer<iImage> &image) {
saveObj(image.dynamicCast<Image>());
}
void BotDataBase::removeImage(const QString &id) {
deleteById<Image>(id, &Image::setId);
}
QSharedPointer<iRecord>
SecretDataBase::getRecordByHash(const QByteArray &hash, bool ifNotExistsCreate) {
}
bool SecretDataBase::saveRecord(const QSharedPointer<iRecord> &record) {
}
}

@ -5,7 +5,7 @@
//# of this license document, but changing it is not allowed.
//#
#include <YourTimeDeliviry/idatabase.h>
#include <SecretDB/idatabase.h>
#include <database.h>
@ -14,50 +14,16 @@
namespace QASecret {
class BotDataBase: public IDataBase, public QH::DataBase
class SecretDataBase: public IDataBase, public QH::DataBase
{
public:
BotDataBase();
SecretDataBase();
// IDataBase interface
public:
QSet<unsigned long long> getProcessedIds() override;
void addProcessedId(unsigned long long id) override;
void removeProcessedId(unsigned long long id) override;
void setProcessedIds(const QSet<unsigned long long> &ids) override;
QSharedPointer<iUser> getUserById(unsigned long long id, bool ifNotExistsCreate = false) override;
QList<QSharedPointer<iUser> > getAllUsers(iRole::RoleName roleName = iRole::All) override;
void saveUser(const QSharedPointer<iUser> &user) override;
void removeUser(unsigned long long id) override;
QSharedPointer<iRole> getRoleByUserId(unsigned long long userId, bool ifNotExistsCreate = false) override;
void saveRole(const QSharedPointer<iRole> &role) override;
void removeRole(unsigned long long userId) override;
QSharedPointer<iMenuItem> getMenuById(int id, bool ifNotExistsCreate = false) override;
QList<QSharedPointer<iMenuItem> > getAllMenuItems() override;
void saveMenuItem(const QSharedPointer<iMenuItem> &menuItem) override;
unsigned int insertMenuItem(const QSharedPointer<iMenuItem> &menuItem) override;
void removeMenuItem(int id) override;
void clearMenuTable() const override;
QSharedPointer<iMenuItem> makeMenuItem() override;
QSharedPointer<iOrder> getOrderById(int id, bool ifNotExistsCreate = false) override;
QList<QSharedPointer<iOrder> > getAllOrders(iOrder::State state = iOrder::State::All) override;
void saveOrder(const QSharedPointer<iOrder> &order) override;
unsigned int insertOrder(const QSharedPointer<iOrder> &order) override;
QSharedPointer<iOrder> makeOrder() override;
void removeOrder(int id) override;
QList<QSharedPointer<iImage> > getAllImages() override;
QSharedPointer<iImage> getImageById(const QString &id, bool ifNotExistsCreate = false) override;
void saveImage(const QSharedPointer<iImage> &image) override;
void removeImage(const QString &id) override;
QSharedPointer<iRecord> getRecordByAlias(const QString &alias, bool ifNotExistsCreate) override;
QSharedPointer<iRecord> getRecordByHash(const QByteArray &hash, bool ifNotExistsCreate) override;
bool saveRecord(const QSharedPointer<iRecord> &record) override;
};
}

@ -7,7 +7,7 @@
#include "SecretDB.h"
#include <botdatabase.h>
#include <secretdatabase.h>
namespace QASecret {
@ -18,7 +18,7 @@ bool init() {
}
QSharedPointer<IDataBase> database() {
auto db = QSharedPointer<BotDataBase>::create();
auto db = QSharedPointer<SecretDataBase>::create();
db->initSqlDb();
return db;

@ -30,160 +30,22 @@ public:
* @param ifNotExistsCreate - this option will create a new object if object with @a id is not existst into database. But object wil not save into database.
* @return A QSharedPointer to the user object if found, nullptr otherwise.
*/
virtual QSharedPointer<iUser> getRecordByAlias(const QString& alias, bool ifNotExistsCreate = false) = 0;
virtual QSharedPointer<iRecord> getRecordByAlias(const QString& alias, bool ifNotExistsCreate = false) = 0;
/**
* @brief Get a list of all users in the database.
* @return A list of QSharedPointer<iUser> objects.
*/
virtual QList<QSharedPointer<iUser>> getAllUsers(iRole::RoleName roleName = iRole::All) = 0;
/**
* @brief Update old, or insert if not exists a new user to the database.
* @param user The user object to add.
*/
virtual void saveUser(const QSharedPointer<iUser>& user) = 0;
/**
* @brief Remove a user from the database by their ID.
* @param id The ID of the user to remove.
*/
virtual void removeUser(unsigned long long id) = 0;
/**
* @brief Get a user's role by their ID.
* @param userId The ID of the user.
* @brief getRecordByHash Get record by hash.
* @param hash The hash of the user to retrieve.
* @param ifNotExistsCreate - this option will create a new object if object with @a id is not existst into database. But object wil not save into database.
* @return A QSharedPointer to the role object if found, nullptr otherwise.
* @return A QSharedPointer to the user object if found, nullptr otherwise.
*/
virtual QSharedPointer<iRole> getRoleByUserId(unsigned long long userId, bool ifNotExistsCreate = false) = 0;
virtual QSharedPointer<iRecord> getRecordByHash(const QByteArray& hash, bool ifNotExistsCreate = false) = 0;
/**
* @brief Update old, or insert if not exists a new role to the database.
* @param role The role object to add.
* @brief saveRecord This method save a record object into database.
* @param record - this is object tah will be saved into database
* @return true if the object will save
*/
virtual void saveRole(const QSharedPointer<iRole>& role) = 0;
/**
* @brief Remove a role from the database by the user's ID.
* @param userId The ID of the user whose role should be removed.
*/
virtual void removeRole(unsigned long long userId) = 0;
/**
* @brief Get a menu item by its ID.
* @param id The ID of the menu item to retrieve.
* @param ifNotExistsCreate - this option will create a new object if object with @a id is not existst into database. But object wil not save into database.
* @return A QSharedPointer to the menu item object if found, nullptr otherwise.
*/
virtual QSharedPointer<iMenuItem> getMenuById(int id, bool ifNotExistsCreate = false) = 0;
/**
* @brief Get a list of all menu items in the database.
* @return A list of QSharedPointer<iMenu> objects.
*/
virtual QList<QSharedPointer<iMenuItem>> getAllMenuItems() = 0;
/**
* @brief Update old, or insert if not exists a new menu item to the database.
* @param menuItem The menu item object to add.
*/
virtual void saveMenuItem(const QSharedPointer<iMenuItem>& menuItem) = 0;
/**
* @brief insertMenuItem This method create a new record of the menuItem and return them id
* @param menuItem This is data to save.
* @return id of the new record of the @a menuItem
*/
virtual unsigned int insertMenuItem(const QSharedPointer<iMenuItem> &menuItem) = 0;
/**
* @brief Remove a menu item from the database by its ID.
* @param id The ID of the menu item to remove.
*/
virtual void removeMenuItem(int id) = 0;
/**
* @brief clearMenuTable This method remove all data from the menu table.
*/
virtual void clearMenuTable() const = 0;
/**
* @brief makeMenuItem This method create a new record of the menu item in database.
* @return new record of the menu item.
*/
virtual QSharedPointer<iMenuItem> makeMenuItem() = 0;
/**
* @brief Get an order by its ID.
* @param id The ID of the order to retrieve.\
* @param ifNotExistsCreate - this option will create a new object if object with @a id is not existst into database. But object wil not save into database.
* @return A QSharedPointer to the order object if found, nullptr otherwise.
*/
virtual QSharedPointer<iOrder> getOrderById(int id, bool ifNotExistsCreate = false) = 0;
/**
* @brief Get a list of all orders in the database.
* @param state filter order by status. If you want to get all orders with all statuses use the iOrder::State:All
* @return A list of QSharedPointer<iOrder> objects.
*/
virtual QList<QSharedPointer<iOrder>> getAllOrders(iOrder::State state = iOrder::State::All) = 0;
/**
* @brief Update old, or insert if not exists a new order to the database.
* @param order The order object to add.
*/
virtual void saveOrder(const QSharedPointer<iOrder>& order) = 0;
/**
* @brief insertOrder This method create a new record of the order and return them id
* @param order This is data to save.
* @return id of the new record of the @a order
*/
virtual unsigned int insertOrder(const QSharedPointer<iOrder> &order) = 0;
/**
* @brief makeOrder This method create a new record of the order into database.
* @return new record of the order.
*/
virtual QSharedPointer<iOrder> makeOrder() = 0;
/**
* @brief Remove an order from the database by its ID.
* @param id The ID of the order to remove.
*/
virtual void removeOrder(int id) = 0;
/**
* @brief Get a list of all images in the database.
* @return A list of QSharedPointer<iImage> objects.
*/
virtual QList<QSharedPointer<iImage>> getAllImages() = 0;
/**
* @brief Update old, or insert if not exists a new image to the database.
* @param image The order object to add.
*/
virtual void saveImage(const QSharedPointer<iImage>& image) = 0;
/**
* @brief Remove an image from the database by its ID.
* @param id The ID of the image to remove.
*/
virtual void removeImage(const QString& id) = 0;
/**
* @brief Get an image by its ID.
* @param id The ID of the image to retrieve.\
* @param ifNotExistsCreate - this option will create a new object if object with @a id is not existst into database. But object wil not save into database.
* @return A QSharedPointer to the image object if found, nullptr otherwise.
*/
virtual QSharedPointer<iImage> getImageById(const QString &id, bool ifNotExistsCreate = false) = 0;
virtual bool saveRecord(const QSharedPointer<iRecord>& record) = 0;
};
}

@ -1,32 +1,9 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "ProcessedIds" (
"id" BIGINT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "Orders" (
"id" INTEGER NOT NULL PRIMARY KEY,
"time" INTEGER NOT NULL,
"finishTime" INTEGER NOT NULL,
"accepted" BOOLEAN NOT NULL DEFAULT false,
"done" BOOLEAN NOT NULL DEFAULT false,
"delivered" BOOLEAN NOT NULL DEFAULT false,
"courier" INTEGER DEFAULT NULL,
"receiver" INTEGER DEFAULT NULL,
"manufacturer" INTEGER DEFAULT NULL,
"data" BLOB NOT NULL,
FOREIGN KEY (courier) REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (receiver) REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (manufacturer) REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE
CREATE TABLE IF NOT EXISTS "Records" (
"hash" VARCHAR NOT NULL UNIQUE,
"alias" VARCHAR DEFAULT NULL UNIQUE,
"data" BLOB NOT NULL
);
COMMIT;