From 9af086151e6d9d3fe88f9e3e21797812a3e701ba Mon Sep 17 00:00:00 2001 From: dec05eba <0xdec05eba@gmail.com> Date: Mon, 14 May 2018 00:20:11 +0200 Subject: Replace files with sqlite Using sqlite because sqlite has transactions, storing/loading from files automatically, unloading data that is not accessed often. Removed cosmetic data (node name, username). They can be added using addData by the application that uses odhtdb instead. Database callback functions can now be called with stored data using database.loadNode function. TODO: Add local user storage (with password) back, it has been temorary disabled --- include/odhtdb/Database.hpp | 56 ++++++++------ include/odhtdb/DatabaseStorage.hpp | 134 ++++++++++++++++------------------ include/odhtdb/Encryption.hpp | 3 + include/odhtdb/Group.hpp | 15 +--- include/odhtdb/LocalUser.hpp | 6 +- include/odhtdb/LocalUserEncrypted.hpp | 15 +--- include/odhtdb/Permission.hpp | 2 +- include/odhtdb/RemoteUser.hpp | 6 +- include/odhtdb/Signature.hpp | 8 +- include/odhtdb/User.hpp | 15 +--- include/odhtdb/sql/SqlQuery.hpp | 65 +++++++++++++++++ 11 files changed, 181 insertions(+), 144 deletions(-) create mode 100644 include/odhtdb/sql/SqlQuery.hpp (limited to 'include') diff --git a/include/odhtdb/Database.hpp b/include/odhtdb/Database.hpp index 12c618b..1e4d470 100644 --- a/include/odhtdb/Database.hpp +++ b/include/odhtdb/Database.hpp @@ -55,14 +55,14 @@ namespace odhtdb const Hash *nodeHash; u64 timestamp; // In microseconds - const User *creatorUser; - std::string name; + const Signature::PublicKey *creatorPublicKey; + const DataView groupId; - DatabaseCreateNodeRequest(const Hash *_nodeHash, u64 _timestamp, const User *_creatorUser, std::string &&_name) : + DatabaseCreateNodeRequest(const Hash *_nodeHash, u64 _timestamp, const Signature::PublicKey *_creatorPublicKey, const DataView &_groupId) : nodeHash(_nodeHash), timestamp(_timestamp), - creatorUser(_creatorUser), - name(std::move(_name)) + creatorPublicKey(_creatorPublicKey), + groupId(_groupId) { } @@ -75,14 +75,14 @@ namespace odhtdb const Hash *nodeHash; const Hash *requestHash; u64 timestamp; // In microseconds - const User *creatorUser; + const Signature::PublicKey *creatorPublicKey; const DataView decryptedData; - DatabaseAddNodeRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const User *_creatorUser, const DataView &_decryptedData) : + DatabaseAddNodeRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const Signature::PublicKey *_creatorPublicKey, const DataView &_decryptedData) : nodeHash(_nodeHash), requestHash(_requestHash), timestamp(_timestamp), - creatorUser(_creatorUser), + creatorPublicKey(_creatorPublicKey), decryptedData(_decryptedData) { @@ -96,16 +96,16 @@ namespace odhtdb const Hash *nodeHash; const Hash *requestHash; u64 timestamp; // In microseconds - const User *creatorUser; - const User *userToAdd; - const Group *groupToAddUserTo; + const Signature::PublicKey *creatorPublicKey; + const Signature::PublicKey *userToAddPublicKey; + const DataView groupToAddUserTo; - DatabaseAddUserRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const User *_creatorUser, const User *_userToAdd, const Group *_groupToAddUserTo) : + DatabaseAddUserRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const Signature::PublicKey *_creatorPublicKey, const Signature::PublicKey *_userToAddPublicKey, const DataView &_groupToAddUserTo) : nodeHash(_nodeHash), requestHash(_requestHash), timestamp(_timestamp), - creatorUser(_creatorUser), - userToAdd(_userToAdd), + creatorPublicKey(_creatorPublicKey), + userToAddPublicKey(_userToAddPublicKey), groupToAddUserTo(_groupToAddUserTo) { @@ -115,7 +115,7 @@ namespace odhtdb class DatabaseCreateResponse { public: - DatabaseCreateResponse(LocalUser *nodeAdminUser, const std::shared_ptr &key, const std::shared_ptr &hash); + DatabaseCreateResponse(LocalUser *nodeAdminUser, std::shared_ptr key, std::shared_ptr hash); const LocalUser* getNodeAdminUser() const; // Size of encryption key is odhtdb::KEY_BYTE_SIZE (found in Encryption.hpp) @@ -144,32 +144,40 @@ namespace odhtdb reponseKeyInfoHash = other.reponseKeyInfoHash; } }; + + using CreateNodeCallbackFunc = std::function; + using AddNodeCallbackFunc = std::function; + using AddUserCallbackFunc = std::function; + + struct DatabaseCallbackFuncs + { + CreateNodeCallbackFunc createNodeCallbackFunc; + AddNodeCallbackFunc addNodeCallbackFunc; + AddUserCallbackFunc addUserCallbackFunc; + }; + class Database { DISABLE_COPY(Database) friend class DatabaseStorage; public: - Database(const char *bootstrapNodeAddr, u16 port, const boost::filesystem::path &storageDir); + Database(const char *bootstrapNodeAddr, u16 port, const boost::filesystem::path &storageDir, DatabaseCallbackFuncs callbackFuncs); ~Database(); // Safe to call multiple times with same node hash, will be ignored if the node is already beeing seeded void seed(const DatabaseNode &nodeToSeed); void stopSeeding(const Hash &nodeHash); + void loadNode(const Hash &nodeHash); // Throws DatabaseCreateException on failure. - std::unique_ptr create(const std::string &ownerName, const std::string &nodeName); + std::unique_ptr create(); // Throws DatabaseCreateException on failure. - std::unique_ptr create(const std::string &ownerName, const Signature::KeyPair &keyPair, const std::string &nodeName); + std::unique_ptr create(const Signature::KeyPair &creatorKeyPair); // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add data to node void addData(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, DataView dataToAdd); // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo - void addUser(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, const std::string &userToAddName, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo); - - void setOnCreateNodeCallback(std::function callbackFunc); - void setOnAddNodeCallback(std::function callbackFunc); - void setOnAddUserCallback(std::function callbackFunc); + void addUser(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo); - DatabaseStorage& getStorage(); ntp::NtpTimestamp getSyncedTimestampUtc() const; private: void deserializeCreateRequest(const std::shared_ptr &value, const Hash &hash, const std::shared_ptr encryptionKey); diff --git a/include/odhtdb/DatabaseStorage.hpp b/include/odhtdb/DatabaseStorage.hpp index 11e243a..3c4d9bc 100644 --- a/include/odhtdb/DatabaseStorage.hpp +++ b/include/odhtdb/DatabaseStorage.hpp @@ -15,6 +15,10 @@ #include #include #include +#include + +class sqlite3; +class sqlite3_stmt; namespace odhtdb { @@ -41,16 +45,12 @@ namespace odhtdb { Signature::PublicKey creatorPublicKey; DataView data; - u32 offsetToEncryptedData; u64 createdTimestamp; // In microseconds - std::string nodeName; - bool isDecrypted; std::vector groups; std::vector objects; DatabaseStorageObjectList(const Signature::PublicKey &_creatorPublicKey) : - creatorPublicKey(_creatorPublicKey), - isDecrypted(false) + creatorPublicKey(_creatorPublicKey) { } @@ -115,63 +115,46 @@ namespace odhtdb LocalUser *localUser; }; + using FetchNodeRawCallbackFunc = std::function; + using FetchNodeAddDataRawCallbackFunc = std::function; + class DatabaseStorage { public: - // Throws DatabaseStorageCorrupt if storage is corrupted + // Throws DatabaseStorageCorrupt if storage is corrupted. Throws DatabaseStorageException on other failures DatabaseStorage(Database *database, const boost::filesystem::path &storagePath); + ~DatabaseStorage(); + + void loadNode(const Hash &nodeHash); + + bool doesNodeExist(const Hash &nodeHash) const; + bool doesDataExist(const Hash &requestHash) const; // Throws DatabaseStorageAlreadyExists if data with hash already exists - void createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const u8 *data, usize dataSize, u32 offsetToEncryptedData); + void createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const void *data, usize size); // 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, DatabaseOperation operation, const User *creatorUser, u64 timestamp, const u8 *data, usize dataSize, const DataView &encryptedDataView); - - // 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); - - // Return false if group with id already exists, otherwise return true - bool addGroup(const Hash &nodeHash, Group *group); + void appendStorage(const Hash &nodeHash, const Hash &dataHash, DatabaseOperation operation, const Signature::PublicKey &creatorPublicKey, u64 timestamp, const void *data, usize size, const DataView &additionalDataView); - // Return false if user public key already exists, otherwise return true - bool addUser(const Hash &nodeHash, User *user); + // Throws DatabaseStorageAlreadyExists if group already exists in node + void addGroup(const Hash &nodeHash, Group *group); - // Increase user action counter, returning the new value. If user has not performed any action yet, then 0 is returned. - // Returns DatabaseStorageException if no node with id @nodeHash exists or if user with public key @userPublicKey doesn't exist in node @nodeHash - //u64 increaseUserActionCounter(const Hash &nodeHash, const Signature::PublicKey &userPublicKey); + void addUserToGroup(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupId); - // Returns nullptr if no storage with provided hash exists - const DatabaseStorageObjectList* getStorage(const Hash &hash) const; + // Throws DatabaseStorageAlreadyExists is user already exists in node + void addUser(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupId); - // Returns nullptr if node @nodeHash doesn't exist - const DataViewMap* getNodeGroups(const Hash &nodeHash); - - // Returns nullptr if a group with id @groupId doesn't exist in node @nodeHash or if no node with id @nodeHash exists - Group* getGroupById(const Hash &nodeHash, uint8_t groupId[GROUP_ID_LENGTH]) const; - - // Returns nullptr if node @nodeHash doesn't exist - const Signature::MapPublicKey* getNodeUsers(const Hash &nodeHash); - - // Returns nullptr if a user with public key @publicKey doesn't exist in node @nodeHash or if no node with id @nodeHash exists - User* getUserByPublicKey(const Hash &nodeHash, const Signature::PublicKey &userPublicKey) const; + void fetchNodeRaw(const Hash &nodeHash, FetchNodeRawCallbackFunc callbackFunc); + void fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc); // Username and key pair has to be unique, returns true on success - bool storeLocalUser(const std::string &username, const Signature::KeyPair &keyPair, const std::string &password); + //bool storeLocalUser(const std::string &username, const Signature::KeyPair &keyPair, const std::string &password); // Returns public key and private key of encrypted local user. // Throws DatabaseStorageNoSuchLocalStorageUser if user does not exist in local storage. // Throws DatabaseStorageWrongPassword if password for the stored local user is wrong. - Signature::KeyPair decryptLocalEncryptedUser(const std::string &username, const std::string &password); - - // Get stored local user by public & private key in all nodes they exist. - // Creates a new user object and replaces user object in the nodes. - // Safe to call multiple times. - std::vector getLocalNodeUsers(const Signature::KeyPair &keyPair); - - // Returns data in node by its id. Doesn't include 'create' requests. - // Returns nullptr if not data with @dataHash exists. - DatabaseStorageObject* getDataById(const Hash &dataHash); + //Signature::KeyPair decryptLocalEncryptedUser(const std::string &username, const std::string &password); // Returns true and node decryption key if node exists and we have the decryption key, // otherwise return false and OwnedMemory with data set to nullptr @@ -183,37 +166,48 @@ namespace odhtdb // Update storage state (remove quarantine objects if they are too old, etc) void update(); private: - void loadGroupsFromFile(); - void loadUsersFromFile(); - void loadDataFromFile(); - void loadLocalUsersFromFile(); - void loadNodeDecryptionKeysFromFile(); - void loadDecryptedDataFromFile(); + void init(const boost::filesystem::path &storagePath); + void cleanup(); + + void bindCheckError(int sqliteBindResult); void loadMetadataFromFile(); - void loadStorageCreate(sibs::SafeDeserializer &deserializer); - void loadStorageAppend(sibs::SafeDeserializer &deserializer); - void loadDecryptedStorageCreate(sibs::SafeDeserializer &deserializer); - void loadDecryptedStorageAddData(sibs::SafeDeserializer &deserializer); - void loadDecryptedStorageAddUser(sibs::SafeDeserializer &deserializer); - - bool decryptNodeData(const Hash &nodeHash, DatabaseStorageObjectList *databaseCreateObject, const std::shared_ptr decryptionKey); - bool decryptNodeAppendedData(const Hash &nodeHash, DatabaseStorageObject *databaseAppendObject, const std::shared_ptr decryptionKey); + bool decryptNodeData(const Hash &nodeHash, const std::shared_ptr decryptionKey); + bool decryptNodeData(const Hash &nodeHash, const std::shared_ptr decryptionKey, const Signature::PublicKey *creatorPublicKey, const DataView &adminGroupId, u64 timestamp); + bool decryptNodeAddData(i64 rowId, const Hash &nodeHash, const Hash &dataHash, u64 timestamp, const Signature::PublicKey *creatorPublicKey, const DataView &encryptedData, const std::shared_ptr decryptionKey); + bool decryptNodeAddUser(i64 rowId, const Hash &nodeHash, const Hash &dataHash, u64 timestamp, const Signature::PublicKey *creatorPublicKey, const Signature::PublicKey *userToAddPublicKey, const DataView &groupToAddUserTo, const std::shared_ptr decryptionKey); + i64 getNodeRowId(const Hash &nodeHash); + i64 getNodeAddDataRowId(const Hash &requestHash); + + void setNodeAddDataDecrypted(i64 rowId); + void setNodeAddDataDecryptedData(i64 rowId, const DataView &decryptedData); private: Database *database; - DatabaseStorageMap storageMap; - DatabaseStorageQuarantineMap quarantineStorageMap; - MapHash storedDataHash; // Prevent duplicate data from being added - MapHash*> nodePublicKeyUserDataMap; - MapHash*> nodeGroupByIdMap; - MapHash> nodeDecryptionKeyMap; - std::unordered_map nameLocalUsersMap; - boost::filesystem::path groupsFilePath; - boost::filesystem::path usersFilePath; - boost::filesystem::path dataFilePath; + sqlite3 *sqliteDb; + sqlite3_stmt *insertNodeStmt; + sqlite3_stmt *insertUserStmt; + sqlite3_stmt *insertGroupStmt; + sqlite3_stmt *insertNodeAddDataStmt; + sqlite3_stmt *setNodeDecryptionKeyStmt; + sqlite3_stmt *getNodeDecryptionKeyStmt; + sqlite3_stmt *insertNodeUserGroupAssocStmt; + + sqlite3_stmt *selectNodeStmt; + sqlite3_stmt *selectNodeAddDataByNodeStmt; + sqlite3_stmt *selectNodeIdStatement; + sqlite3_stmt *selectNodeAddDataIdStatement; + sqlite3_stmt *insertNodeRawStmt; + sqlite3_stmt *insertNodeAddDataRawStmt; + + sqlite3_stmt *insertNodeAddDataAdditionalStmt; + sqlite3_stmt *insertNodeAddUserDataStmt; + + sqlite3_stmt *selectNodeAddDataAdditionalStmt; + sqlite3_stmt *selectNodeAddUserDataStmt; + + sqlite3_stmt *setNodeAddDataDecryptedStmt; + sqlite3_stmt *setNodeAddDataAdditionalDataStmt; + boost::filesystem::path metadataFilePath; - boost::filesystem::path localUsersFilePath; - boost::filesystem::path nodeDecryptionKeysFilePath; - boost::filesystem::path decryptedDataFilePath; u8 passwordSalt[PASSWORD_SALT_LEN]; std::pair, std::shared_ptr> identity; }; diff --git a/include/odhtdb/Encryption.hpp b/include/odhtdb/Encryption.hpp index e710760..2457630 100644 --- a/include/odhtdb/Encryption.hpp +++ b/include/odhtdb/Encryption.hpp @@ -38,6 +38,9 @@ namespace odhtdb DataView getKey() const; DataView getNonce() const; DataView getCipherText() const; + + // Size of output should be at least @ENCRYPTION_KEY_BYTE_SIZE bytes + static void generateKey(unsigned char *output); private: unsigned char key[ENCRYPTION_KEY_BYTE_SIZE]; unsigned char nonce[ENCRYPTION_NONCE_BYTE_SIZE]; diff --git a/include/odhtdb/Group.hpp b/include/odhtdb/Group.hpp index 99307e1..f8de78e 100644 --- a/include/odhtdb/Group.hpp +++ b/include/odhtdb/Group.hpp @@ -4,7 +4,6 @@ #include "DataView.hpp" #include "Permission.hpp" #include "utils.hpp" -#include #include #include @@ -12,16 +11,6 @@ namespace odhtdb { class User; - class GroupNameTooLongException : public std::runtime_error - { - public: - GroupNameTooLongException(const std::string &groupName) : - std::runtime_error(std::string("The group name ") + groupName + " is longer than 255 bytes") - { - - } - }; - const int GROUP_ID_LENGTH = 16; class Group @@ -29,10 +18,9 @@ namespace odhtdb DISABLE_COPY(Group) friend class User; public: - Group(const std::string &name, uint8_t id[GROUP_ID_LENGTH], const Permission &permission); + Group(uint8_t id[GROUP_ID_LENGTH], const Permission &permission); ~Group(); - const std::string& getName() const; DataView getId() const; const Permission& getPermission() const; const std::vector& getUsers() const; @@ -40,7 +28,6 @@ namespace odhtdb void addUser(const User *user); bool removeUser(const User *user); private: - std::string name; uint8_t id[GROUP_ID_LENGTH]; Permission permission; std::vector users; diff --git a/include/odhtdb/LocalUser.hpp b/include/odhtdb/LocalUser.hpp index c87ba45..b60b516 100644 --- a/include/odhtdb/LocalUser.hpp +++ b/include/odhtdb/LocalUser.hpp @@ -8,9 +8,9 @@ namespace odhtdb class LocalUser : public User { public: - static LocalUser* create(const Signature::KeyPair &keyPair, const std::string &name, Group *group) + static LocalUser* create(const Signature::KeyPair &keyPair, Group *group) { - return new LocalUser(keyPair, name, group); + return new LocalUser(keyPair, group); } const Signature::PublicKey& getPublicKey() const override @@ -28,7 +28,7 @@ namespace odhtdb return keyPair; } private: - LocalUser(const Signature::KeyPair &_keyPair, const std::string &name, Group *group); + LocalUser(const Signature::KeyPair &_keyPair, Group *group); private: Signature::KeyPair keyPair; }; diff --git a/include/odhtdb/LocalUserEncrypted.hpp b/include/odhtdb/LocalUserEncrypted.hpp index 952892f..7919cb3 100644 --- a/include/odhtdb/LocalUserEncrypted.hpp +++ b/include/odhtdb/LocalUserEncrypted.hpp @@ -22,9 +22,9 @@ namespace odhtdb class LocalUserEncrypted { public: - static LocalUserEncrypted* create(const Signature::PublicKey &publicKey, const EncryptedPrivateKey &encryptedPrivateKey, const std::string &name) + static LocalUserEncrypted* create(const Signature::PublicKey &publicKey, const EncryptedPrivateKey &encryptedPrivateKey) { - return new LocalUserEncrypted(publicKey, encryptedPrivateKey, name); + return new LocalUserEncrypted(publicKey, encryptedPrivateKey); } const Signature::PublicKey& getPublicKey() const @@ -36,22 +36,15 @@ namespace odhtdb { return encryptedPrivateKey; } - - const std::string& getName() const - { - return name; - } private: - LocalUserEncrypted(const Signature::PublicKey &_publicKey, const EncryptedPrivateKey &_encryptedPrivateKey, const std::string &_name) : + LocalUserEncrypted(const Signature::PublicKey &_publicKey, const EncryptedPrivateKey &_encryptedPrivateKey) : publicKey(_publicKey), - encryptedPrivateKey(_encryptedPrivateKey), - name(_name) + encryptedPrivateKey(_encryptedPrivateKey) { } private: Signature::PublicKey publicKey; EncryptedPrivateKey encryptedPrivateKey; - std::string name; }; } diff --git a/include/odhtdb/Permission.hpp b/include/odhtdb/Permission.hpp index 1e7bb0c..0978c5e 100644 --- a/include/odhtdb/Permission.hpp +++ b/include/odhtdb/Permission.hpp @@ -16,7 +16,7 @@ namespace odhtdb { ADD_DATA = (1 << 0), ADD_USER_SAME_LEVEL = (1 << 1), - ADD_USER_LOWER_LEVEL = (1 << 2), + ADD_USER_HIGHER_LEVEL = (1 << 2), ADD_GROUP = (1 << 3), REMOVE_GROUP = (1 << 4) }; diff --git a/include/odhtdb/RemoteUser.hpp b/include/odhtdb/RemoteUser.hpp index 9dc8f96..2658132 100644 --- a/include/odhtdb/RemoteUser.hpp +++ b/include/odhtdb/RemoteUser.hpp @@ -7,9 +7,9 @@ namespace odhtdb class RemoteUser : public User { public: - static RemoteUser* create(const Signature::PublicKey &publicKey, const std::string &name, Group *group) + static RemoteUser* create(const Signature::PublicKey &publicKey, Group *group) { - return new RemoteUser(publicKey, name, group); + return new RemoteUser(publicKey, group); } const Signature::PublicKey& getPublicKey() const override @@ -17,7 +17,7 @@ namespace odhtdb return publicKey; } private: - RemoteUser(const Signature::PublicKey &_publicKey, const std::string &name, Group *group) : User(User::Type::REMOTE, name, group), publicKey(_publicKey){} + RemoteUser(const Signature::PublicKey &_publicKey, Group *group) : User(User::Type::REMOTE, group), publicKey(_publicKey) {} private: Signature::PublicKey publicKey; }; diff --git a/include/odhtdb/Signature.hpp b/include/odhtdb/Signature.hpp index 1f5158e..0fc9087 100644 --- a/include/odhtdb/Signature.hpp +++ b/include/odhtdb/Signature.hpp @@ -55,11 +55,13 @@ namespace odhtdb public: const static PublicKey ZERO; + PublicKey(); // Throws InvalidSignatureKeySize if size is not PUBLIC_KEY_NUM_BYTES PublicKey(const char *data, size_t size); PublicKey(const PublicKey &other); PublicKey& operator=(const PublicKey &other); + char* getData() { return data; } const char* getData() const { return data; } size_t getSize() const { return PUBLIC_KEY_NUM_BYTES; } @@ -73,8 +75,6 @@ namespace odhtdb bool operator!=(const PublicKey &other) const; std::string toString() const; - private: - PublicKey(){} private: char data[PUBLIC_KEY_NUM_BYTES]; }; @@ -96,19 +96,19 @@ namespace odhtdb public: const static PrivateKey ZERO; + PrivateKey(); // Throws InvalidSignatureKeySize if size is not PRIVATE_KEY_NUM_BYTES PrivateKey(const char *data, size_t size); PrivateKey(const PrivateKey &other); PrivateKey& operator=(const PrivateKey &other); + char* getData() { return data; } const char* getData() const { return data; } size_t getSize() const { return PRIVATE_KEY_NUM_BYTES; } // Throws DataSignException if signing data failed for whatever reason. This wont happen unless there is an issue with the private key std::string sign(const DataView &dataToSign) const; std::string toString() const; - private: - PrivateKey(){} private: char data[PRIVATE_KEY_NUM_BYTES]; }; diff --git a/include/odhtdb/User.hpp b/include/odhtdb/User.hpp index 4d6d9b3..15e6492 100644 --- a/include/odhtdb/User.hpp +++ b/include/odhtdb/User.hpp @@ -3,7 +3,6 @@ #include "Signature.hpp" #include "types.hpp" #include "Permission.hpp" -#include #include #include @@ -11,16 +10,6 @@ namespace odhtdb { class Group; class DatabaseStorage; - - class UserNameTooLongException : public std::runtime_error - { - public: - UserNameTooLongException(const std::string &userName) : - std::runtime_error(std::string("The username ") + userName + " is longer than 255 bytes") - { - - } - }; class User { @@ -37,16 +26,14 @@ namespace odhtdb virtual void addToGroup(Group *group); Type getType() const { return type; } - const std::string& getName() const { return name; } virtual const std::vector& getGroups() const { return groups; } virtual const Signature::PublicKey& getPublicKey() const = 0; virtual bool isAllowedToPerformAction(PermissionType action) const; protected: - User(Type type, const std::string &name, Group *group); + User(Type type, Group *group); protected: Type type; - std::string name; std::vector groups; }; } diff --git a/include/odhtdb/sql/SqlQuery.hpp b/include/odhtdb/sql/SqlQuery.hpp new file mode 100644 index 0000000..f26ee1a --- /dev/null +++ b/include/odhtdb/sql/SqlQuery.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include "../DataView.hpp" +#include +#include + +class sqlite3; +class sqlite3_stmt; + +namespace odhtdb +{ + class SqlQueryException : public std::runtime_error + { + public: + SqlQueryException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class SqlArg + { + public: + enum class Type : u8 + { + DATA_VIEW, + INT, + INT64 + }; + + SqlArg(const DataView &data) : dataView(data), type(Type::DATA_VIEW) {} + SqlArg(int data) : integer(data), type(Type::INT) {} + SqlArg(i64 data) : integer64(data), type(Type::INT64) {} + + int bind(sqlite3_stmt *stmt, int paramIndex) const; + private: + union + { + const DataView dataView; + const int integer; + const i64 integer64; + }; + const Type type; + }; + + class SqlQuery + { + public: + // Throws SqlQueryException on failure + SqlQuery(sqlite3 *db, const char *sql, std::initializer_list args); + ~SqlQuery(); + + // Return true if we got result, false if there are not rows left. + // Throws SqlQueryException on failure + bool next(); + + int getInt(int index); + i64 getInt64(int index); + // The returned blob is NOT a copy, it will be invalid after next call to @next or when SqlQuery is deallocated + const DataView getBlob(int index); + private: + void checkColumnIndex(int index); + private: + sqlite3 *db; + sqlite3_stmt *stmt; + int numColumns; + }; +} -- cgit v1.2.3