#pragma once #include "types.hpp" #include "Hash.hpp" #include "DataView.hpp" #include "Signature.hpp" #include "Encryption.hpp" #include #include namespace odhtdb { class Group; class User; struct DatabaseStorageObject { DataView data; u64 createdTimestamp; // In microseconds Signature::PublicKey creatorPublicKey; DatabaseStorageObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey); }; struct DatabaseStorageObjectList { DataView data; u64 createdTimestamp; // In microseconds std::vector groups; std::vector objects; }; struct DatabaseStorageQuarantineObject { DataView data; u64 createdTimestamp; // In microseconds u64 storedTimestamp; // In microseconds Signature::PublicKey creatorPublicKey; DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey); }; class DatabaseStorageAlreadyExists : public std::runtime_error { public: DatabaseStorageAlreadyExists(const std::string &errMsg) : std::runtime_error(errMsg) {} }; class DatabaseStorageNotFound : public std::runtime_error { public: DatabaseStorageNotFound(const std::string &errMsg) : std::runtime_error(errMsg) {} }; using DatabaseStorageMap = MapHash; using DatabaseStorageQuarantineMap = Signature::MapPublicKey>; class DatabaseStorage { public: // Throws DatabaseStorageAlreadyExists if data with hash already exists void createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const u8 *data, usize dataSize); // Throws DatabaseStorageNotFound if data with @nodeHash hash has not been created yet. // Throws DatabaseStorageAlreadyExists if same data has been added before (hash of @data, in @dataHash) void appendStorage(const Hash &nodeHash, const Hash &dataHash, const User *creatorUser, u64 timestamp, const u8 *data, usize dataSize); // Throws DatabaseStorageAlreadyExists if same data has been added before (hash of @data, in @dataHash) void addToQuarantine(const Hash &dataHash, const Signature::PublicKey &creatorPublicKey, u64 timestamp, const u8 *data, usize dataSize); void addUser(User *user, const Hash &hash); // Returns nullptr if no storage with provided hash exists const DatabaseStorageObjectList* getStorage(const Hash &hash) const; // Returns nullptr if no node with the user exists const Hash* getNodeByUserPublicKey(const Signature::PublicKey &userPublicKey) const; // Returns nullptr if no user with public key exists const User* getUserByPublicKey(const Signature::PublicKey &userPublicKey) const; // Returns nullptr if a group with id @groupId doesn't exist Group* getGroupById(uint8_t groupId[16]); // Update storage state (remove quarantine objects if they are too old, etc) void update(); private: DatabaseStorageMap storageMap; DatabaseStorageQuarantineMap quarantineStorageMap; SetHash storedDataHash; // Prevent duplicate data from being added Signature::MapPublicKey userPublicKeyNodeMap; Signature::MapPublicKey publicKeyUserMap; DataViewMap groupByIdMap; }; }