aboutsummaryrefslogtreecommitdiff
path: root/src/DatabaseStorage.cpp
blob: 638eac0a0f3936eb6230fc1cb4927eaa4a798071 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "../include/DatabaseStorage.hpp"
#include "../include/Group.hpp"
#include "../include/User.hpp"
#include <cstring>
#include <chrono>

using namespace std;

namespace odhtdb
{
    DatabaseStorageObject::DatabaseStorageObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey) : 
        data(_data), createdTimestamp(_timestamp), creatorPublicKey(_creatorPublicKey)
    {
        
    }
    
    DatabaseStorageQuarantineObject::DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey) : 
        data(_data), createdTimestamp(_timestamp), creatorPublicKey(_creatorPublicKey)
    {
        auto time = chrono::high_resolution_clock::now().time_since_epoch();
        storedTimestamp = chrono::duration_cast<chrono::microseconds>(time).count();
    }
    
    void DatabaseStorage::createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const u8 *data, usize dataSize)
    {
        if(storageMap.find(hash) != storageMap.end())
        {
            string errMsg = "Database storage with hash ";
            errMsg += hash.toString();
            errMsg += " already exists";
            throw DatabaseStorageAlreadyExists(errMsg);
        }
        
        DatabaseStorageObjectList *databaseStorageObjectList = new DatabaseStorageObjectList();
        databaseStorageObjectList->createdTimestamp = timestamp;
        databaseStorageObjectList->groups.push_back(creatorGroup);
        databaseStorageObjectList->data = DataView(new u8[dataSize], dataSize);
        memcpy(databaseStorageObjectList->data.data, data, dataSize);
        storageMap[hash] = databaseStorageObjectList;
        
        for(auto user : creatorGroup->getUsers())
        {
            userPublicKeyNodeMap[user->getPublicKey()] = hash;
            publicKeyUserMap[user->getPublicKey()] = user;
        }
    }
    
    void DatabaseStorage::appendStorage(const Hash &hash, const User *creatorUser, u64 timestamp, const u8 *data, usize dataSize)
    {
        auto it = storageMap.find(hash);
        if(it == storageMap.end())
        {
            string errMsg = "Database storage with hash ";
            errMsg += hash.toString();
            errMsg += " not found. Storage for a hash needs to be created before data can be appended to it";
            throw DatabaseStorageNotFound(errMsg);
        }
        
        DataView storageData { new u8[dataSize], dataSize };
        DatabaseStorageObject *databaseStorageObject = new DatabaseStorageObject(storageData, timestamp, creatorUser->getPublicKey());
        it->second->objects.push_back(databaseStorageObject);
    }
    
    void DatabaseStorage::addToQuarantine(const Signature::PublicKey &creatorPublicKey, u64 timestamp, const u8 *data, usize dataSize)
    {
        DataView storageData { new u8[dataSize], dataSize };
        memcpy(storageData.data, data, dataSize);
        DatabaseStorageQuarantineObject *databaseQuarantineStorageObject = new DatabaseStorageQuarantineObject(storageData, timestamp, creatorPublicKey);
        quarantineStorageMap[creatorPublicKey].emplace_back(databaseQuarantineStorageObject);
    }
    
    const DatabaseStorageObjectList* DatabaseStorage::getStorage(const Hash &hash) const
    {
        auto it = storageMap.find(hash);
        if(it != storageMap.end())
            return it->second;
        return nullptr;
    }
    
    const Hash* DatabaseStorage::getNodeByUserPublicKey(const Signature::PublicKey &userPublicKey) const
    {
        auto it = userPublicKeyNodeMap.find(userPublicKey);
        if(it != userPublicKeyNodeMap.end())
            return &it->second;
        return nullptr;
    }
    
    // Returns nullptr if no user with public key exists
    const User* DatabaseStorage::getUserByPublicKey(const Signature::PublicKey &userPublicKey) const
    {
        auto it = publicKeyUserMap.find(userPublicKey);
        if(it != publicKeyUserMap.end())
            return it->second;
        return nullptr;
    }
}