summaryrefslogtreecommitdiff
path: root/discord
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2020-12-10 03:50:40 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2020-12-10 03:50:40 -0500
commit850b87c1ec0ac1abfc9a3ed5c566bbe98fba9e7c (patch)
treef2e990e7a1a84ffa3f2e825ac7e1380826d7de9e /discord
parente04545287519123982b7baa9c29dc175d4e35405 (diff)
downloadabaddon-portaudio-850b87c1ec0ac1abfc9a3ed5c566bbe98fba9e7c.tar.gz
abaddon-portaudio-850b87c1ec0ac1abfc9a3ed5c566bbe98fba9e7c.zip
cache channels
Diffstat (limited to 'discord')
-rw-r--r--discord/channel.hpp36
-rw-r--r--discord/discord.cpp45
-rw-r--r--discord/discord.hpp2
-rw-r--r--discord/guild.cpp14
-rw-r--r--discord/store.cpp270
-rw-r--r--discord/store.hpp12
6 files changed, 250 insertions, 129 deletions
diff --git a/discord/channel.hpp b/discord/channel.hpp
index 178f8b6..5f8e5e3 100644
--- a/discord/channel.hpp
+++ b/discord/channel.hpp
@@ -17,24 +17,24 @@ enum class ChannelType : int {
};
struct Channel {
- Snowflake ID; //
- ChannelType Type; //
- Snowflake GuildID; // opt
- int Position = -1; // opt
- std::vector<PermissionOverwrite> PermissionOverwrites; // opt
- std::string Name; // opt, null (null for dm's)
- std::string Topic; // opt, null
- bool IsNSFW = false; // opt
- Snowflake LastMessageID; // opt, null
- int Bitrate = 0; // opt
- int UserLimit = 0; // opt
- int RateLimitPerUser = 0; // opt
- std::vector<User> Recipients; // opt
- std::string Icon; // opt, null
- Snowflake OwnerID; // opt
- Snowflake ApplicationID; // opt
- Snowflake ParentID; // opt, null
- std::string LastPinTimestamp; // opt, can be null even tho docs say otherwise
+ Snowflake ID;
+ ChannelType Type;
+ std::optional<Snowflake> GuildID;
+ std::optional<int> Position;
+ std::optional<std::vector<PermissionOverwrite>> PermissionOverwrites; // shouldnt be accessed
+ std::optional<std::string> Name; // null for dm's
+ std::optional<std::string> Topic; // null
+ std::optional<bool> IsNSFW;
+ std::optional<Snowflake> LastMessageID; // null
+ std::optional<int> Bitrate;
+ std::optional<int> UserLimit;
+ std::optional<int> RateLimitPerUser;
+ std::optional<std::vector<User>> Recipients; // only access id
+ std::optional<std::string> Icon; // null
+ std::optional<Snowflake> OwnerID;
+ std::optional<Snowflake> ApplicationID;
+ std::optional<Snowflake> ParentID; // null
+ std::optional<std::string> LastPinTimestamp; // null
friend void from_json(const nlohmann::json &j, Channel &m);
void update_from_json(const nlohmann::json &j);
diff --git a/discord/discord.cpp b/discord/discord.cpp
index 50446a7..c86cc3b 100644
--- a/discord/discord.cpp
+++ b/discord/discord.cpp
@@ -161,7 +161,7 @@ std::optional<Message> DiscordClient::GetMessage(Snowflake id) const {
return m_store.GetMessage(id);
}
-const Channel *DiscordClient::GetChannel(Snowflake id) const {
+std::optional<Channel> DiscordClient::GetChannel(Snowflake id) const {
return m_store.GetChannel(id);
}
@@ -247,9 +247,9 @@ bool DiscordClient::HasGuildPermission(Snowflake user_id, Snowflake guild_id, Pe
}
bool DiscordClient::HasChannelPermission(Snowflake user_id, Snowflake channel_id, Permission perm) const {
- const auto *channel = m_store.GetChannel(channel_id);
- if (channel == nullptr) return false;
- const auto base = ComputePermissions(user_id, channel->GuildID);
+ const auto channel = m_store.GetChannel(channel_id);
+ if (!channel.has_value()) return false;
+ const auto base = ComputePermissions(user_id, *channel->GuildID);
const auto overwrites = ComputeOverwrites(base, user_id, channel_id);
return (overwrites & perm) == perm;
}
@@ -284,13 +284,13 @@ Permission DiscordClient::ComputeOverwrites(Permission base, Snowflake member_id
if ((base & Permission::ADMINISTRATOR) == Permission::ADMINISTRATOR)
return Permission::ALL;
- const auto *channel = GetChannel(channel_id);
- const auto member = GetMember(member_id, channel->GuildID);
- if (!member.has_value() || channel == nullptr)
+ const auto channel = GetChannel(channel_id);
+ const auto member = GetMember(member_id, *channel->GuildID);
+ if (!member.has_value() || !channel.has_value())
return Permission::NONE;
Permission perms = base;
- const auto overwrite_everyone = GetPermissionOverwrite(channel_id, channel->GuildID);
+ const auto overwrite_everyone = GetPermissionOverwrite(channel_id, *channel->GuildID);
if (overwrite_everyone.has_value()) {
perms &= ~overwrite_everyone->Deny;
perms |= overwrite_everyone->Allow;
@@ -359,7 +359,7 @@ void DiscordClient::SendLazyLoad(Snowflake id) {
std::make_pair(100, 199)
};
msg.Channels = c;
- msg.GuildID = GetChannel(id)->GuildID;
+ msg.GuildID = *GetChannel(id)->GuildID;
msg.ShouldGetActivities = false;
msg.ShouldGetTyping = false;
@@ -401,8 +401,9 @@ void DiscordClient::CreateDM(Snowflake user_id) {
std::optional<Snowflake> DiscordClient::FindDM(Snowflake user_id) {
const auto &channels = m_store.GetChannels();
- for (const auto &[id, channel] : channels) {
- if (channel.Recipients.size() == 1 && channel.Recipients[0].ID == user_id)
+ for (const auto &id : channels) {
+ const auto channel = m_store.GetChannel(id);
+ if (channel->Recipients->size() == 1 && channel->Recipients.value()[0].ID == user_id)
return id;
}
@@ -579,7 +580,7 @@ void DiscordClient::ProcessNewGuild(Guild &guild) {
c.GuildID = guild.ID;
m_store.SetChannel(c.ID, c);
m_guild_to_channels[guild.ID].insert(c.ID);
- for (auto &p : c.PermissionOverwrites) {
+ for (auto &p : *c.PermissionOverwrites) {
m_store.SetPermissionOverwrite(c.ID, p.ID, p);
}
}
@@ -602,7 +603,7 @@ void DiscordClient::HandleGatewayReady(const GatewayMessage &msg) {
m_store.BeginTransaction();
for (const auto &dm : data.PrivateChannels) {
m_store.SetChannel(dm.ID, dm);
- for (const auto &recipient : dm.Recipients)
+ for (const auto &recipient : *dm.Recipients)
m_store.SetUser(recipient.ID, recipient);
}
m_store.EndTransaction();
@@ -665,8 +666,8 @@ void DiscordClient::HandleGatewayPresenceUpdate(const GatewayMessage &msg) {
void DiscordClient::HandleGatewayChannelDelete(const GatewayMessage &msg) {
const auto id = msg.Data.at("id").get<Snowflake>();
- const auto *channel = GetChannel(id);
- auto it = m_guild_to_channels.find(channel->GuildID);
+ const auto channel = GetChannel(id);
+ auto it = m_guild_to_channels.find(*channel->GuildID);
if (it != m_guild_to_channels.end())
it->second.erase(id);
m_store.ClearChannel(id);
@@ -675,9 +676,10 @@ void DiscordClient::HandleGatewayChannelDelete(const GatewayMessage &msg) {
void DiscordClient::HandleGatewayChannelUpdate(const GatewayMessage &msg) {
const auto id = msg.Data.at("id").get<Snowflake>();
- auto *cur = m_store.GetChannel(id);
- if (cur != nullptr) {
+ auto cur = m_store.GetChannel(id);
+ if (cur.has_value()) {
cur->update_from_json(msg.Data);
+ m_store.SetChannel(id, *cur);
m_signal_channel_update.emit(id);
}
}
@@ -686,8 +688,8 @@ void DiscordClient::HandleGatewayChannelCreate(const GatewayMessage &msg) {
Channel data = msg.Data;
m_store.BeginTransaction();
m_store.SetChannel(data.ID, data);
- m_guild_to_channels[data.GuildID].insert(data.ID);
- for (const auto &p : data.PermissionOverwrites)
+ m_guild_to_channels[*data.GuildID].insert(data.ID);
+ for (const auto &p : *data.PermissionOverwrites)
m_store.SetPermissionOverwrite(data.ID, p.ID, p);
m_store.EndTransaction();
m_signal_channel_create.emit(data.ID);
@@ -799,8 +801,9 @@ void DiscordClient::AddUserToGuild(Snowflake user_id, Snowflake guild_id) {
std::set<Snowflake> DiscordClient::GetPrivateChannels() const {
auto ret = std::set<Snowflake>();
- for (const auto &[id, chan] : m_store.GetChannels()) {
- if (chan.Type == ChannelType::DM || chan.Type == ChannelType::GROUP_DM)
+ for (const auto &id : m_store.GetChannels()) {
+ const auto chan = m_store.GetChannel(id);
+ if (chan->Type == ChannelType::DM || chan->Type == ChannelType::GROUP_DM)
ret.insert(id);
}
diff --git a/discord/discord.hpp b/discord/discord.hpp
index b915d8c..17187d5 100644
--- a/discord/discord.hpp
+++ b/discord/discord.hpp
@@ -80,7 +80,7 @@ public:
void FetchMessagesInChannel(Snowflake id, std::function<void(const std::vector<Snowflake> &)> cb);
void FetchMessagesInChannelBefore(Snowflake channel_id, Snowflake before_id, std::function<void(const std::vector<Snowflake> &)> cb);
std::optional<Message> GetMessage(Snowflake id) const;
- const Channel *GetChannel(Snowflake id) const;
+ std::optional<Channel> GetChannel(Snowflake id) const;
std::optional<Emoji> GetEmoji(Snowflake id) const;
std::optional<PermissionOverwrite> GetPermissionOverwrite(Snowflake channel_id, Snowflake id) const;
std::optional<User> GetUser(Snowflake id) const;
diff --git a/discord/guild.cpp b/discord/guild.cpp
index 31b4dd6..2663aac 100644
--- a/discord/guild.cpp
+++ b/discord/guild.cpp
@@ -136,14 +136,14 @@ std::vector<Snowflake> Guild::GetSortedChannels(Snowflake ignore) const {
std::map<int, std::vector<const Channel *>> position_to_categories;
std::map<int, std::vector<const Channel *>> orphan_channels;
for (const auto &channel_id : channels) {
- const auto *data = discord.GetChannel(channel_id);
- if (data == nullptr) continue;
- if (!data->ParentID.IsValid() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
- orphan_channels[data->Position].push_back(data);
- else if (data->ParentID.IsValid() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
- category_to_channels[data->ParentID].push_back(data);
+ const auto data = discord.GetChannel(channel_id);
+ if (!data.has_value()) continue;
+ if (!data->ParentID->IsValid() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
+ orphan_channels[*data->Position].push_back(&*data);
+ else if (data->ParentID->IsValid() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
+ category_to_channels[*data->ParentID].push_back(&*data);
else if (data->Type == ChannelType::GUILD_CATEGORY)
- position_to_categories[data->Position].push_back(data);
+ position_to_categories[*data->Position].push_back(&*data);
}
for (auto &[pos, channels] : orphan_channels) {
diff --git a/discord/store.cpp b/discord/store.cpp
index 12f729f..e5dcd19 100644
--- a/discord/store.cpp
+++ b/discord/store.cpp
@@ -51,28 +51,60 @@ bool Store::IsValid() const {
return m_db_err == SQLITE_OK;
}
-void Store::SetUser(Snowflake id, const User &user) {
- Bind(m_set_user_stmt, 1, id);
- Bind(m_set_user_stmt, 2, user.Username);
- Bind(m_set_user_stmt, 3, user.Discriminator);
- Bind(m_set_user_stmt, 4, user.Avatar);
- Bind(m_set_user_stmt, 5, user.IsBot);
- Bind(m_set_user_stmt, 6, user.IsSystem);
- Bind(m_set_user_stmt, 7, user.IsMFAEnabled);
- Bind(m_set_user_stmt, 8, user.Locale);
- Bind(m_set_user_stmt, 9, user.IsVerified);
- Bind(m_set_user_stmt, 10, user.Email);
- Bind(m_set_user_stmt, 11, user.Flags);
- Bind(m_set_user_stmt, 12, user.PremiumType);
- Bind(m_set_user_stmt, 13, user.PublicFlags);
-
- if (!RunInsert(m_set_user_stmt)) {
- fprintf(stderr, "user insert failed: %s\n", sqlite3_errstr(m_db_err));
+void Store::SetChannel(Snowflake id, const Channel &chan) {
+ Bind(m_set_chan_stmt, 1, id);
+ Bind(m_set_chan_stmt, 2, static_cast<int>(chan.Type));
+ Bind(m_set_chan_stmt, 3, chan.GuildID);
+ Bind(m_set_chan_stmt, 4, chan.Position);
+ Bind(m_set_chan_stmt, 5, nullptr); // unused
+ Bind(m_set_chan_stmt, 6, chan.Name);
+ Bind(m_set_chan_stmt, 7, chan.Topic);
+ Bind(m_set_chan_stmt, 8, chan.IsNSFW);
+ Bind(m_set_chan_stmt, 9, chan.LastMessageID);
+ Bind(m_set_chan_stmt, 10, chan.Bitrate);
+ Bind(m_set_chan_stmt, 11, chan.UserLimit);
+ Bind(m_set_chan_stmt, 12, chan.RateLimitPerUser);
+ if (chan.Recipients.has_value()) {
+ std::vector<Snowflake> ids;
+ for (const auto &u : *chan.Recipients)
+ ids.push_back(u.ID);
+ Bind(m_set_chan_stmt, 13, nlohmann::json(ids).dump());
+ } else {
+ Bind(m_set_chan_stmt, 13, nullptr);
}
+ Bind(m_set_chan_stmt, 14, chan.Icon);
+ Bind(m_set_chan_stmt, 15, chan.OwnerID);
+ Bind(m_set_chan_stmt, 16, chan.ApplicationID);
+ Bind(m_set_chan_stmt, 17, chan.ParentID);
+ Bind(m_set_chan_stmt, 18, chan.LastPinTimestamp);
+
+ if (!RunInsert(m_set_chan_stmt))
+ fprintf(stderr, "channel insert failed: %s\n", sqlite3_errstr(m_db_err));
+
+ m_channels.insert(id);
}
-void Store::SetChannel(Snowflake id, const Channel &channel) {
- m_channels[id] = channel;
+void Store::SetEmoji(Snowflake id, const Emoji &emoji) {
+ Bind(m_set_emote_stmt, 1, id);
+ Bind(m_set_emote_stmt, 2, emoji.Name);
+
+ if (emoji.Roles.has_value())
+ Bind(m_set_emote_stmt, 3, nlohmann::json(*emoji.Roles).dump());
+ else
+ Bind(m_set_emote_stmt, 3, nullptr);
+
+ if (emoji.Creator.has_value())
+ Bind(m_set_emote_stmt, 4, emoji.Creator->ID);
+ else
+ Bind(m_set_emote_stmt, 4, nullptr);
+
+ Bind(m_set_emote_stmt, 5, emoji.NeedsColons);
+ Bind(m_set_emote_stmt, 6, emoji.IsManaged);
+ Bind(m_set_emote_stmt, 7, emoji.IsAnimated);
+ Bind(m_set_emote_stmt, 8, emoji.IsAvailable);
+
+ if (!RunInsert(m_set_emote_stmt))
+ fprintf(stderr, "emoji insert failed: %s\n", sqlite3_errstr(m_db_err));
}
void Store::SetGuild(Snowflake id, const Guild &guild) {
@@ -131,18 +163,18 @@ void Store::SetGuild(Snowflake id, const Guild &guild) {
m_guilds.insert(id);
}
-void Store::SetRole(Snowflake id, const Role &role) {
- Bind(m_set_role_stmt, 1, id);
- Bind(m_set_role_stmt, 2, role.Name);
- Bind(m_set_role_stmt, 3, role.Color);
- Bind(m_set_role_stmt, 4, role.IsHoisted);
- Bind(m_set_role_stmt, 5, role.Position);
- Bind(m_set_role_stmt, 6, static_cast<uint64_t>(role.Permissions));
- Bind(m_set_role_stmt, 7, role.IsManaged);
- Bind(m_set_role_stmt, 8, role.IsMentionable);
+void Store::SetGuildMember(Snowflake guild_id, Snowflake user_id, const GuildMember &data) {
+ Bind(m_set_member_stmt, 1, user_id);
+ Bind(m_set_member_stmt, 2, guild_id);
+ Bind(m_set_member_stmt, 3, data.Nickname);
+ Bind(m_set_member_stmt, 4, nlohmann::json(data.Roles).dump());
+ Bind(m_set_member_stmt, 5, data.JoinedAt);
+ Bind(m_set_member_stmt, 6, data.PremiumSince);
+ Bind(m_set_member_stmt, 7, data.IsDeafened);
+ Bind(m_set_member_stmt, 8, data.IsMuted);
- if (!RunInsert(m_set_role_stmt))
- fprintf(stderr, "role insert failed: %s\n", sqlite3_errstr(m_db_err));
+ if (!RunInsert(m_set_member_stmt))
+ fprintf(stderr, "member insert failed: %s\n", sqlite3_errstr(m_db_err));
}
void Store::SetMessage(Snowflake id, const Message &message) {
@@ -193,20 +225,6 @@ void Store::SetMessage(Snowflake id, const Message &message) {
fprintf(stderr, "message insert failed: %s\n", sqlite3_errstr(m_db_err));
}
-void Store::SetGuildMember(Snowflake guild_id, Snowflake user_id, const GuildMember &data) {
- Bind(m_set_member_stmt, 1, user_id);
- Bind(m_set_member_stmt, 2, guild_id);
- Bind(m_set_member_stmt, 3, data.Nickname);
- Bind(m_set_member_stmt, 4, nlohmann::json(data.Roles).dump());
- Bind(m_set_member_stmt, 5, data.JoinedAt);
- Bind(m_set_member_stmt, 6, data.PremiumSince);
- Bind(m_set_member_stmt, 7, data.IsDeafened);
- Bind(m_set_member_stmt, 8, data.IsMuted);
-
- if (!RunInsert(m_set_member_stmt))
- fprintf(stderr, "member insert failed: %s\n", sqlite3_errstr(m_db_err));
-}
-
void Store::SetPermissionOverwrite(Snowflake channel_id, Snowflake id, const PermissionOverwrite &perm) {
Bind(m_set_perm_stmt, 1, perm.ID);
Bind(m_set_perm_stmt, 2, channel_id);
@@ -218,27 +236,82 @@ void Store::SetPermissionOverwrite(Snowflake channel_id, Snowflake id, const Per
fprintf(stderr, "permission insert failed: %s\n", sqlite3_errstr(m_db_err));
}
-void Store::SetEmoji(Snowflake id, const Emoji &emoji) {
- Bind(m_set_emote_stmt, 1, id);
- Bind(m_set_emote_stmt, 2, emoji.Name);
+void Store::SetRole(Snowflake id, const Role &role) {
+ Bind(m_set_role_stmt, 1, id);
+ Bind(m_set_role_stmt, 2, role.Name);
+ Bind(m_set_role_stmt, 3, role.Color);
+ Bind(m_set_role_stmt, 4, role.IsHoisted);
+ Bind(m_set_role_stmt, 5, role.Position);
+ Bind(m_set_role_stmt, 6, static_cast<uint64_t>(role.Permissions));
+ Bind(m_set_role_stmt, 7, role.IsManaged);
+ Bind(m_set_role_stmt, 8, role.IsMentionable);
- if (emoji.Roles.has_value())
- Bind(m_set_emote_stmt, 3, nlohmann::json(*emoji.Roles).dump());
- else
- Bind(m_set_emote_stmt, 3, nullptr);
+ if (!RunInsert(m_set_role_stmt))
+ fprintf(stderr, "role insert failed: %s\n", sqlite3_errstr(m_db_err));
+}
- if (emoji.Creator.has_value())
- Bind(m_set_emote_stmt, 4, emoji.Creator->ID);
- else
- Bind(m_set_emote_stmt, 4, nullptr);
+void Store::SetUser(Snowflake id, const User &user) {
+ Bind(m_set_user_stmt, 1, id);
+ Bind(m_set_user_stmt, 2, user.Username);
+ Bind(m_set_user_stmt, 3, user.Discriminator);
+ Bind(m_set_user_stmt, 4, user.Avatar);
+ Bind(m_set_user_stmt, 5, user.IsBot);
+ Bind(m_set_user_stmt, 6, user.IsSystem);
+ Bind(m_set_user_stmt, 7, user.IsMFAEnabled);
+ Bind(m_set_user_stmt, 8, user.Locale);
+ Bind(m_set_user_stmt, 9, user.IsVerified);
+ Bind(m_set_user_stmt, 10, user.Email);
+ Bind(m_set_user_stmt, 11, user.Flags);
+ Bind(m_set_user_stmt, 12, user.PremiumType);
+ Bind(m_set_user_stmt, 13, user.PublicFlags);
- Bind(m_set_emote_stmt, 5, emoji.NeedsColons);
- Bind(m_set_emote_stmt, 6, emoji.IsManaged);
- Bind(m_set_emote_stmt, 7, emoji.IsAnimated);
- Bind(m_set_emote_stmt, 8, emoji.IsAvailable);
+ if (!RunInsert(m_set_user_stmt)) {
+ fprintf(stderr, "user insert failed: %s\n", sqlite3_errstr(m_db_err));
+ }
+}
- if (!RunInsert(m_set_emote_stmt))
- fprintf(stderr, "emoji insert failed: %s\n", sqlite3_errstr(m_db_err));
+std::optional<Channel> Store::GetChannel(Snowflake id) const {
+ Bind(m_get_chan_stmt, 1, id);
+ if (!FetchOne(m_get_chan_stmt)) {
+ if (m_db_err != SQLITE_DONE)
+ fprintf(stderr, "error while fetching channel: %s\n", sqlite3_errstr(m_db_err));
+ Reset(m_get_chan_stmt);
+ return std::nullopt;
+ }
+
+ Channel ret;
+ ret.ID = id;
+ int tmpi;
+ Get(m_get_chan_stmt, 1, tmpi);
+ ret.Type = static_cast<ChannelType>(tmpi);
+ Get(m_get_chan_stmt, 2, ret.GuildID);
+ Get(m_get_chan_stmt, 3, ret.Position);
+ ret.PermissionOverwrites = std::nullopt;
+ Get(m_get_chan_stmt, 5, ret.Name);
+ Get(m_get_chan_stmt, 6, ret.Topic);
+ Get(m_get_chan_stmt, 7, ret.IsNSFW);
+ Get(m_get_chan_stmt, 8, ret.LastMessageID);
+ Get(m_get_chan_stmt, 9, ret.Bitrate);
+ Get(m_get_chan_stmt, 10, ret.UserLimit);
+ Get(m_get_chan_stmt, 11, ret.RateLimitPerUser);
+ if (!IsNull(m_get_chan_stmt, 12)) {
+ std::string tmps;
+ Get(m_get_chan_stmt, 12, tmps);
+ // dummy users
+ ret.Recipients = std::vector<User>();
+ auto ids = nlohmann::json::parse(tmps).get<std::vector<Snowflake>>();
+ for (const auto &id : ids)
+ ret.Recipients->emplace_back().ID = id;
+ }
+ Get(m_get_chan_stmt, 13, ret.Icon);
+ Get(m_get_chan_stmt, 14, ret.OwnerID);
+ Get(m_get_chan_stmt, 15, ret.ApplicationID);
+ Get(m_get_chan_stmt, 16, ret.ParentID);
+ Get(m_get_chan_stmt, 17, ret.LastPinTimestamp);
+
+ Reset(m_get_chan_stmt);
+
+ return ret;
}
std::optional<Emoji> Store::GetEmoji(Snowflake id) const {
@@ -488,20 +561,6 @@ std::optional<User> Store::GetUser(Snowflake id) const {
return ret;
}
-Channel *Store::GetChannel(Snowflake id) {
- auto it = m_channels.find(id);
- if (it == m_channels.end())
- return nullptr;
- return &it->second;
-}
-
-const Channel *Store::GetChannel(Snowflake id) const {
- auto it = m_channels.find(id);
- if (it == m_channels.end())
- return nullptr;
- return &it->second;
-}
-
void Store::ClearGuild(Snowflake id) {
m_guilds.erase(id);
}
@@ -510,7 +569,7 @@ void Store::ClearChannel(Snowflake id) {
m_channels.erase(id);
}
-const Store::channels_type &Store::GetChannels() const {
+const std::unordered_set<Snowflake> &Store::GetChannels() const {
return m_channels;
}
@@ -668,6 +727,29 @@ lazy BOOL
)
)";
+ constexpr char *create_channels = R"(
+CREATE TABLE IF NOT EXISTS channels (
+id INTEGER PRIMARY KEY,
+type INTEGER NOT NULL,
+guild_id INTEGER,
+position INTEGER,
+overwrites TEXT, /* json */
+name TEXT,
+topic TEXT,
+is_nsfw BOOL,
+last_message_id INTEGER,
+bitrate INTEGER,
+user_limit INTEGER,
+rate_limit INTEGER,
+recipients TEXT, /* json */
+icon TEXT,
+owner_id INTEGER,
+application_id INTEGER,
+parent_id INTEGER,
+last_pin_timestamp TEXT
+)
+)";
+
m_db_err = sqlite3_exec(m_db, create_users, nullptr, nullptr, nullptr);
if (m_db_err != SQLITE_OK) {
fprintf(stderr, "failed to create user table: %s\n", sqlite3_errstr(m_db_err));
@@ -710,6 +792,12 @@ lazy BOOL
return false;
}
+ m_db_err = sqlite3_exec(m_db, create_channels, nullptr, nullptr, nullptr);
+ if (m_db_err != SQLITE_OK) {
+ fprintf(stderr, "failed to create channels table: %s\n", sqlite3_errstr(m_db_err));
+ return false;
+ }
+
return true;
}
@@ -776,7 +864,7 @@ SELECT * FROM members WHERE user_id = ? AND guild_id = ?
constexpr const char *set_guild = R"(
REPLACE INTO guilds VALUES (
-?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
+ ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
)";
@@ -784,6 +872,16 @@ REPLACE INTO guilds VALUES (
SELECT * FROM guilds WHERE id = ?
)";
+ constexpr const char *set_chan = R"(
+REPLACE INTO channels VALUES (
+ ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
+)
+)";
+
+ constexpr const char *get_chan = R"(
+SELECT * FROM channels WHERE id = ?
+)";
+
m_db_err = sqlite3_prepare_v2(m_db, set_user, -1, &m_set_user_stmt, nullptr);
if (m_db_err != SQLITE_OK) {
fprintf(stderr, "failed to prepare set user statement: %s\n", sqlite3_errstr(m_db_err));
@@ -868,6 +966,18 @@ SELECT * FROM guilds WHERE id = ?
return false;
}
+ m_db_err = sqlite3_prepare_v2(m_db, set_chan, -1, &m_set_chan_stmt, nullptr);
+ if (m_db_err != SQLITE_OK) {
+ fprintf(stderr, "failed to prepare set channel statement: %s\n", sqlite3_errstr(m_db_err));
+ return false;
+ }
+
+ m_db_err = sqlite3_prepare_v2(m_db, get_chan, -1, &m_get_chan_stmt, nullptr);
+ if (m_db_err != SQLITE_OK) {
+ fprintf(stderr, "failed to prepare get channel statement: %s\n", sqlite3_errstr(m_db_err));
+ return false;
+ }
+
return true;
}
@@ -886,6 +996,8 @@ void Store::Cleanup() {
sqlite3_finalize(m_get_member_stmt);
sqlite3_finalize(m_set_guild_stmt);
sqlite3_finalize(m_get_guild_stmt);
+ sqlite3_finalize(m_set_chan_stmt);
+ sqlite3_finalize(m_get_chan_stmt);
}
void Store::Bind(sqlite3_stmt *stmt, int index, int num) const {
@@ -959,6 +1071,10 @@ void Store::Get(sqlite3_stmt *stmt, int index, Snowflake &out) const {
out = static_cast<uint64_t>(num);
}
+bool Store::IsNull(sqlite3_stmt *stmt, int index) const {
+ return sqlite3_column_type(stmt, index) == SQLITE_NULL;
+}
+
void Store::Reset(sqlite3_stmt *stmt) const {
sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
diff --git a/discord/store.hpp b/discord/store.hpp
index 6d1987f..b08be07 100644
--- a/discord/store.hpp
+++ b/discord/store.hpp
@@ -19,7 +19,7 @@ public:
bool IsValid() const;
void SetUser(Snowflake id, const User &user);
- void SetChannel(Snowflake id, const Channel &channel);
+ void SetChannel(Snowflake id, const Channel &chan);
void SetGuild(Snowflake id, const Guild &guild);
void SetRole(Snowflake id, const Role &role);
void SetMessage(Snowflake id, const Message &message);
@@ -29,7 +29,7 @@ public:
// slap const on everything even tho its not *really* const
- Channel *GetChannel(Snowflake id);
+ std::optional<Channel> GetChannel(Snowflake id) const;
std::optional<Emoji> GetEmoji(Snowflake id) const;
std::optional<Guild> GetGuild(Snowflake id) const;
std::optional<GuildMember> GetGuildMember(Snowflake guild_id, Snowflake user_id) const;
@@ -37,7 +37,6 @@ public:
std::optional<PermissionOverwrite> GetPermissionOverwrite(Snowflake channel_id, Snowflake id) const;
std::optional<Role> GetRole(Snowflake id) const;
std::optional<User> GetUser(Snowflake id) const;
- const Channel *GetChannel(Snowflake id) const;
void ClearGuild(Snowflake id);
void ClearChannel(Snowflake id);
@@ -51,7 +50,7 @@ public:
using permission_overwrites_type = std::unordered_map<Snowflake, std::unordered_map<Snowflake, PermissionOverwrite>>; // [channel][user/role]
using emojis_type = std::unordered_map<Snowflake, Emoji>;
- const channels_type &GetChannels() const;
+ const std::unordered_set<Snowflake> &GetChannels() const;
const std::unordered_set<Snowflake> &GetGuilds() const;
void ClearAll();
@@ -60,7 +59,7 @@ public:
void EndTransaction();
private:
- channels_type m_channels;
+ std::unordered_set<Snowflake> m_channels;
std::unordered_set<Snowflake> m_guilds;
bool CreateTables();
@@ -83,6 +82,7 @@ private:
void Get(sqlite3_stmt *stmt, int index, std::string &out) const;
void Get(sqlite3_stmt *stmt, int index, bool &out) const;
void Get(sqlite3_stmt *stmt, int index, Snowflake &out) const;
+ bool IsNull(sqlite3_stmt *stmt, int index) const;
void Reset(sqlite3_stmt *stmt) const;
std::filesystem::path m_db_path;
@@ -102,6 +102,8 @@ private:
mutable sqlite3_stmt *m_get_member_stmt;
mutable sqlite3_stmt *m_set_guild_stmt;
mutable sqlite3_stmt *m_get_guild_stmt;
+ mutable sqlite3_stmt *m_set_chan_stmt;
+ mutable sqlite3_stmt *m_get_chan_stmt;
};
template<typename T>