#pragma once #include #include #include #include #include #include #include namespace ts { namespace server { class VirtualServer; class DataClient; struct ClientDatabaseInfo { ServerId sid; ClientDbId cldbid; std::chrono::time_point created; std::chrono::time_point lastjoin; std::string uniqueId; std::string lastName; uint32_t connections; }; struct CachedPermissionManager { ServerId sid; ClientDbId cldbid; std::weak_ptr manager; std::shared_ptr ownLock; std::chrono::time_point lastAccess; }; struct CachedProperties { ServerId sid; ClientDbId cldbid; std::weak_ptr properties; std::shared_ptr ownLock; std::chrono::time_point lastAccess; }; /* CREATE_TABLE("properties", "`serverId` INTEGER DEFAULT -1, `type` INTEGER, `id` INTEGER, `key` VARCHAR(" UNKNOWN_KEY_LENGTH "), `value` TEXT", command_append_utf8); CREATE_TABLE("permissions", "`serverId` INT NOT NULL, `type` INT, `id` INT, `channelId` INT, `permId` VARCHAR(" UNKNOWN_KEY_LENGTH "), `value` INT, `grant` INT", command_append_utf8); */ struct StartupPermissionEntry { permission::PermissionSqlType type = permission::SQL_PERM_CHANNEL; uint64_t id = 0; ChannelId channelId = 0; std::shared_ptr permission = permission::PermissionTypeEntry::unknown; permission::PermissionValue value = 0; permission::PermissionValue grant = 0; bool flag_skip = false; bool flag_negate = false; }; struct StartupPropertyEntry { property::PropertyType type = property::PropertyType::PROP_TYPE_UNKNOWN; uint64_t id{0}; const property::PropertyDescription* info{&property::undefined_property_description}; std::string value; }; struct StartupCacheEntry { ServerId sid; std::deque> permissions; std::deque> properties; }; struct FastPropertyEntry { const property::PropertyDescription* type; std::string value; }; class DatabaseHelper { public: static std::shared_ptr default_properties_client(std::shared_ptr /* properties */, ClientType /* type */); static bool assignDatabaseId(sql::SqlManager *, ServerId id, std::shared_ptr); static std::mutex database_id_mutex; explicit DatabaseHelper(sql::SqlManager*); ~DatabaseHelper(); void loadStartupCache(); size_t cacheBinarySize(); void clearStartupCache(ServerId sid = 0); void deleteClient(const std::shared_ptr&,ClientDbId); bool validClientDatabaseId(const std::shared_ptr&, ClientDbId); std::deque> queryDatabaseInfo(const std::shared_ptr&, const std::deque&); std::deque> queryDatabaseInfoByUid(const std::shared_ptr &, std::deque); std::shared_ptr loadClientPermissionManager(const std::shared_ptr&, ClientDbId); void saveClientPermissions(const std::shared_ptr&, ClientDbId , const std::shared_ptr& /* permission manager */); std::shared_ptr loadChannelPermissions(const std::shared_ptr&, ChannelId); void saveChannelPermissions(const std::shared_ptr&, ChannelId, const std::shared_ptr& /* permission manager */); std::shared_ptr loadGroupPermissions(const std::shared_ptr&, GroupId); void saveGroupPermissions(const std::shared_ptr&, GroupId, const std::shared_ptr& /* permission manager */); std::shared_ptr loadPlaylistPermissions(const std::shared_ptr&, PlaylistId /* playlist id */); void savePlaylistPermissions(const std::shared_ptr&, PlaylistId, const std::shared_ptr& /* permission manager */); std::shared_ptr loadServerProperties(const std::shared_ptr&); //Read and write std::shared_ptr loadPlaylistProperties(const std::shared_ptr&, PlaylistId); //Read and write std::shared_ptr loadChannelProperties(const std::shared_ptr&, ChannelId); //Read and write std::shared_ptr loadClientProperties(const std::shared_ptr&, ClientDbId, ClientType); bool deleteGroupPermissions(const std::shared_ptr&, GroupId); bool deleteChannelPermissions(const std::shared_ptr&, ChannelId); bool deletePlaylist(const std::shared_ptr&, PlaylistId /* playlist id */); std::deque> query_properties(ServerId /* server */, property::PropertyType /* type */, uint64_t /* id */); /* required for server snapshots */ void tick(); private: void loadStartupPermissionCache(); void loadStartupPropertyCache(); bool use_startup_cache = false; threads::Mutex startup_lock; std::deque> startup_entries; sql::SqlManager* sql = nullptr; threads::Mutex permManagerLock; std::deque cachedPermissionManagers; threads::Mutex propsLock; std::deque cachedProperties; }; } }