diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-11-28 22:48:30 -0500 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-11-28 22:48:30 -0500 |
commit | e1703aea3fd597b23bde90e6c505278c517be611 (patch) | |
tree | 37d98fc90c9cd0844388bfb79beda2204f44af92 /discord/store.cpp | |
parent | fd53a76bf6f53a095a639765923a30f2206b2cd6 (diff) | |
parent | e02107feea8214a045e6faa969f00dcbc0d2b072 (diff) | |
download | abaddon-portaudio-e1703aea3fd597b23bde90e6c505278c517be611.tar.gz abaddon-portaudio-e1703aea3fd597b23bde90e6c505278c517be611.zip |
merge master
Diffstat (limited to 'discord/store.cpp')
-rw-r--r-- | discord/store.cpp | 1507 |
1 files changed, 0 insertions, 1507 deletions
diff --git a/discord/store.cpp b/discord/store.cpp deleted file mode 100644 index bc73f67..0000000 --- a/discord/store.cpp +++ /dev/null @@ -1,1507 +0,0 @@ -#include "store.hpp" - -using namespace std::literals::string_literals; - -// hopefully the casting between signed and unsigned int64 doesnt cause issues - -Store::Store(bool mem_store) { - if (mem_store) { - m_db_path = ":memory:"; - m_db_err = sqlite3_open(":memory:", &m_db); - } else { - m_db_path = std::filesystem::temp_directory_path() / "abaddon-store.db"; - m_db_err = sqlite3_open(m_db_path.string().c_str(), &m_db); - } - - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error opening database: %s\n", sqlite3_errstr(m_db_err)); - return; - } - - // clang-format off - m_db_err = sqlite3_exec(m_db, R"( - PRAGMA writable_schema = 1; - DELETE FROM sqlite_master; - PRAGMA writable_schema = 0; - VACUUM; - PRAGMA integrity_check; - )", nullptr, nullptr, nullptr); - // clang-format on - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to clear database: %s\n", sqlite3_errstr(m_db_err)); - return; - } - - m_db_err = sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "enabling write-ahead-log failed: %s\n", sqlite3_errstr(m_db_err)); - return; - } - - m_db_err = sqlite3_exec(m_db, "PRAGMA synchronous = NORMAL", nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "setting synchronous failed: %s\n", sqlite3_errstr(m_db_err)); - return; - } - - CreateTables(); - CreateStatements(); -} - -Store::~Store() { - Cleanup(); - - m_db_err = sqlite3_close(m_db); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error closing database: %s\n", sqlite3_errstr(m_db_err)); - return; - } - - if (m_db_path != ":memory:") { - std::error_code ec; - std::filesystem::remove(m_db_path, ec); - } -} - -bool Store::IsValid() const { - return m_db_err == SQLITE_OK; -} - -void Store::SetBan(Snowflake guild_id, Snowflake user_id, const BanData &ban) { - Bind(m_set_ban_stmt, 1, guild_id); - Bind(m_set_ban_stmt, 2, user_id); - Bind(m_set_ban_stmt, 3, ban.Reason); - - if (!RunInsert(m_set_ban_stmt)) - fprintf(stderr, "ban insert failed: %s\n", sqlite3_errstr(m_db_err)); -} - -void Store::SetChannel(Snowflake id, const ChannelData &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 if (chan.RecipientIDs.has_value()) { - Bind(m_set_chan_stmt, 13, nlohmann::json(*chan.RecipientIDs).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 (chan.ThreadMetadata.has_value()) { - Bind(m_set_chan_stmt, 19, chan.ThreadMetadata->IsArchived); - Bind(m_set_chan_stmt, 20, chan.ThreadMetadata->AutoArchiveDuration); - Bind(m_set_chan_stmt, 21, chan.ThreadMetadata->ArchiveTimestamp); - } else { - Bind(m_set_chan_stmt, 19, nullptr); - Bind(m_set_chan_stmt, 20, nullptr); - Bind(m_set_chan_stmt, 21, nullptr); - } - - if (!RunInsert(m_set_chan_stmt)) - fprintf(stderr, "channel insert failed: %s\n", sqlite3_errstr(m_db_err)); - - m_channels.insert(id); -} - -void Store::SetEmoji(Snowflake id, const EmojiData &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 GuildData &guild) { - Bind(m_set_guild_stmt, 1, id); - Bind(m_set_guild_stmt, 2, guild.Name); - Bind(m_set_guild_stmt, 3, guild.Icon); - Bind(m_set_guild_stmt, 4, guild.Splash); - Bind(m_set_guild_stmt, 5, guild.IsOwner); - Bind(m_set_guild_stmt, 6, guild.OwnerID); - Bind(m_set_guild_stmt, 7, guild.PermissionsNew); - Bind(m_set_guild_stmt, 8, guild.VoiceRegion); - Bind(m_set_guild_stmt, 9, guild.AFKChannelID); - Bind(m_set_guild_stmt, 10, guild.AFKTimeout); - Bind(m_set_guild_stmt, 11, guild.VerificationLevel); - Bind(m_set_guild_stmt, 12, guild.DefaultMessageNotifications); - std::vector<Snowflake> snowflakes; - if (guild.Roles.has_value()) { - for (const auto &x : *guild.Roles) snowflakes.push_back(x.ID); - Bind(m_set_guild_stmt, 13, nlohmann::json(snowflakes).dump()); - } else { - Bind(m_set_guild_stmt, 13, "[]"s); - } - snowflakes.clear(); - if (guild.Emojis.has_value()) { - for (const auto &x : *guild.Emojis) snowflakes.push_back(x.ID); - Bind(m_set_guild_stmt, 14, nlohmann::json(snowflakes).dump()); - } else { - Bind(m_set_guild_stmt, 14, "[]"s); - } - if (guild.Features.has_value()) - Bind(m_set_guild_stmt, 15, nlohmann::json(*guild.Features).dump()); - else - Bind(m_set_guild_stmt, 15, "[]"s); - Bind(m_set_guild_stmt, 16, guild.MFALevel); - Bind(m_set_guild_stmt, 17, guild.ApplicationID); - Bind(m_set_guild_stmt, 18, guild.IsWidgetEnabled); - Bind(m_set_guild_stmt, 19, guild.WidgetChannelID); - Bind(m_set_guild_stmt, 20, guild.SystemChannelFlags); - Bind(m_set_guild_stmt, 21, guild.RulesChannelID); - Bind(m_set_guild_stmt, 22, guild.JoinedAt); - Bind(m_set_guild_stmt, 23, guild.IsLarge); - Bind(m_set_guild_stmt, 24, guild.IsUnavailable); - Bind(m_set_guild_stmt, 25, guild.MemberCount); - if (guild.Channels.has_value()) { - snowflakes.clear(); - for (const auto &x : *guild.Channels) snowflakes.push_back(x.ID); - Bind(m_set_guild_stmt, 26, nlohmann::json(snowflakes).dump()); - } else - Bind(m_set_guild_stmt, 26, "[]"s); - Bind(m_set_guild_stmt, 27, guild.MaxPresences); - Bind(m_set_guild_stmt, 28, guild.MaxMembers); - Bind(m_set_guild_stmt, 29, guild.VanityURL); - Bind(m_set_guild_stmt, 30, guild.Description); - Bind(m_set_guild_stmt, 31, guild.BannerHash); - Bind(m_set_guild_stmt, 32, guild.PremiumTier); - Bind(m_set_guild_stmt, 33, guild.PremiumSubscriptionCount); - Bind(m_set_guild_stmt, 34, guild.PreferredLocale); - Bind(m_set_guild_stmt, 35, guild.PublicUpdatesChannelID); - Bind(m_set_guild_stmt, 36, guild.MaxVideoChannelUsers); - Bind(m_set_guild_stmt, 37, guild.ApproximateMemberCount); - Bind(m_set_guild_stmt, 38, guild.ApproximatePresenceCount); - Bind(m_set_guild_stmt, 39, guild.IsLazy); - if (guild.Threads.has_value()) { - snowflakes.clear(); - for (const auto &x : *guild.Threads) snowflakes.push_back(x.ID); - Bind(m_set_guild_stmt, 40, nlohmann::json(snowflakes).dump()); - } else - Bind(m_set_guild_stmt, 40, "[]"s); - - if (!RunInsert(m_set_guild_stmt)) - fprintf(stderr, "guild insert failed: %s\n", sqlite3_errstr(m_db_err)); - - m_guilds.insert(id); -} - -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); - Bind(m_set_member_stmt, 9, data.Avatar); - Bind(m_set_member_stmt, 10, data.IsPending); - - 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) { - Bind(m_set_msg_stmt, 1, id); - Bind(m_set_msg_stmt, 2, message.ChannelID); - Bind(m_set_msg_stmt, 3, message.GuildID); - Bind(m_set_msg_stmt, 4, message.Author.ID); - Bind(m_set_msg_stmt, 5, message.Content); - Bind(m_set_msg_stmt, 6, message.Timestamp); - Bind(m_set_msg_stmt, 7, message.EditedTimestamp); - Bind(m_set_msg_stmt, 8, message.IsTTS); - Bind(m_set_msg_stmt, 9, message.DoesMentionEveryone); - Bind(m_set_msg_stmt, 10, nlohmann::json(message.Mentions).dump()); - Bind(m_set_msg_stmt, 11, nlohmann::json(message.Attachments).dump()); - Bind(m_set_msg_stmt, 12, nlohmann::json(message.Embeds).dump()); - Bind(m_set_msg_stmt, 13, message.IsPinned); - Bind(m_set_msg_stmt, 14, message.WebhookID); - Bind(m_set_msg_stmt, 15, static_cast<uint64_t>(message.Type)); - - if (message.Application.has_value()) - Bind(m_set_msg_stmt, 16, nlohmann::json(*message.Application).dump()); - else - Bind(m_set_msg_stmt, 16, nullptr); - - if (message.MessageReference.has_value()) - Bind(m_set_msg_stmt, 17, nlohmann::json(*message.MessageReference).dump()); - else - Bind(m_set_msg_stmt, 17, nullptr); - - if (message.Flags.has_value()) - Bind(m_set_msg_stmt, 18, static_cast<uint64_t>(*message.Flags)); - else - Bind(m_set_msg_stmt, 18, nullptr); - - if (message.Stickers.has_value()) - Bind(m_set_msg_stmt, 19, nlohmann::json(*message.Stickers).dump()); - else - Bind(m_set_msg_stmt, 19, nullptr); - - if (message.Reactions.has_value()) { - std::string tmp = nlohmann::json(*message.Reactions).dump(); - Bind(m_set_msg_stmt, 20, tmp); - } else - Bind(m_set_msg_stmt, 20, nullptr); - Bind(m_set_msg_stmt, 21, message.IsDeleted()); - Bind(m_set_msg_stmt, 22, message.IsEdited()); - Bind(m_set_msg_stmt, 23, message.IsPending); - Bind(m_set_msg_stmt, 24, message.Nonce); // sorry - - if (message.StickerItems.has_value()) { - std::string tmp = nlohmann::json(*message.StickerItems).dump(); - Bind(m_set_msg_stmt, 25, tmp); - } else - Bind(m_set_msg_stmt, 25, nullptr); - - if (!RunInsert(m_set_msg_stmt)) - fprintf(stderr, "message insert failed: %s\n", sqlite3_errstr(m_db_err)); - - if (message.Interaction.has_value()) - SetMessageInteractionPair(id, *message.Interaction); -} - -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); - Bind(m_set_perm_stmt, 3, static_cast<int>(perm.Type)); - Bind(m_set_perm_stmt, 4, static_cast<uint64_t>(perm.Allow)); - Bind(m_set_perm_stmt, 5, static_cast<uint64_t>(perm.Deny)); - - if (!RunInsert(m_set_perm_stmt)) - fprintf(stderr, "permission insert failed: %s\n", sqlite3_errstr(m_db_err)); -} - -void Store::SetRole(Snowflake id, const RoleData &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 (!RunInsert(m_set_role_stmt)) - fprintf(stderr, "role insert failed: %s\n", sqlite3_errstr(m_db_err)); -} - -void Store::SetUser(Snowflake id, const UserData &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)); - } -} - -Message Store::GetMessageBound(sqlite3_stmt *stmt) const { - Message ret; - Get(stmt, 0, ret.ID); - Get(stmt, 1, ret.ChannelID); - Get(stmt, 2, ret.GuildID); - Get(stmt, 3, ret.Author.ID); // yike - Get(stmt, 4, ret.Content); - Get(stmt, 5, ret.Timestamp); - Get(stmt, 6, ret.EditedTimestamp); - Get(stmt, 7, ret.IsTTS); - Get(stmt, 8, ret.DoesMentionEveryone); - std::string tmps; - Get(stmt, 9, tmps); - nlohmann::json::parse(tmps).get_to(ret.Mentions); - Get(stmt, 10, tmps); - nlohmann::json::parse(tmps).get_to(ret.Attachments); - Get(stmt, 11, tmps); - nlohmann::json::parse(tmps).get_to(ret.Embeds); - Get(stmt, 12, ret.IsPinned); - Get(stmt, 13, ret.WebhookID); - uint64_t tmpi; - Get(stmt, 14, tmpi); - ret.Type = static_cast<MessageType>(tmpi); - - Get(stmt, 15, tmps); - if (tmps != "") - ret.Application = nlohmann::json::parse(tmps).get<MessageApplicationData>(); - - Get(stmt, 16, tmps); - if (tmps != "") - ret.MessageReference = nlohmann::json::parse(tmps).get<MessageReferenceData>(); - - Get(stmt, 17, tmpi); - ret.Flags = static_cast<MessageFlags>(tmpi); - - Get(stmt, 18, tmps); - if (tmps != "") - ret.Stickers = nlohmann::json::parse(tmps).get<std::vector<StickerData>>(); - - Get(stmt, 19, tmps); - if (tmps != "") - ret.Reactions = nlohmann::json::parse(tmps).get<std::vector<ReactionData>>(); - - bool tmpb = false; - Get(stmt, 20, tmpb); - if (tmpb) ret.SetDeleted(); - - Get(stmt, 21, tmpb); - if (tmpb) ret.SetEdited(); - - Get(stmt, 22, ret.IsPending); - Get(stmt, 23, ret.Nonce); - - Get(stmt, 24, tmps); - if (tmps != "") - ret.StickerItems = nlohmann::json::parse(tmps).get<std::vector<StickerItem>>(); - - // interaction data from join - - if (!IsNull(stmt, 25)) { - auto &interaction = ret.Interaction.emplace(); - Get(stmt, 25, interaction.ID); - Get(stmt, 26, interaction.Name); - Get(stmt, 27, interaction.Type); - Get(stmt, 28, interaction.User.ID); - } - - Reset(stmt); - - if (ret.MessageReference.has_value() && ret.MessageReference->MessageID.has_value()) { - auto ref = GetMessage(*ret.MessageReference->MessageID); - if (ref.has_value()) - ret.ReferencedMessage = std::make_unique<Message>(std::move(*ref)); - else - ret.ReferencedMessage = nullptr; - } - - return ret; -} - -void Store::SetMessageInteractionPair(Snowflake message_id, const MessageInteractionData &interaction) { - Bind(m_set_msg_interaction_stmt, 1, message_id); - Bind(m_set_msg_interaction_stmt, 2, interaction.ID); - Bind(m_set_msg_interaction_stmt, 3, interaction.Type); - Bind(m_set_msg_interaction_stmt, 4, interaction.Name); - Bind(m_set_msg_interaction_stmt, 5, interaction.User.ID); - - if (!RunInsert(m_set_msg_interaction_stmt)) { - fprintf(stderr, "message interaction insert failed: %s\n", sqlite3_errstr(m_db_err)); - } -} - -std::optional<BanData> Store::GetBan(Snowflake guild_id, Snowflake user_id) const { - Bind(m_get_ban_stmt, 1, guild_id); - Bind(m_get_ban_stmt, 2, user_id); - if (!FetchOne(m_get_ban_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching ban: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_ban_stmt); - return std::nullopt; - } - - BanData ret; - ret.User.ID = user_id; - Get(m_get_ban_stmt, 2, ret.Reason); - - Reset(m_get_ban_stmt); - return ret; -} - -std::vector<BanData> Store::GetBans(Snowflake guild_id) const { - Bind(m_get_bans_stmt, 1, guild_id); - - std::vector<BanData> ret; - while (FetchOne(m_get_bans_stmt)) { - auto &ban = ret.emplace_back(); - Get(m_get_bans_stmt, 1, ban.User.ID); - Get(m_get_bans_stmt, 2, ban.Reason); - } - - Reset(m_get_bans_stmt); - - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching bans: %s\n", sqlite3_errstr(m_db_err)); - return ret; -} - -std::vector<Message> Store::GetLastMessages(Snowflake id, size_t num) const { - auto ids = GetChannelMessageIDs(id); - std::vector<Message> ret; - for (auto it = ids.cend() - std::min(ids.size(), num); it != ids.cend(); it++) - ret.push_back(*GetMessage(*it)); - return ret; -} - -std::vector<Snowflake> Store::GetChannelMessageIDs(Snowflake id) const { - std::vector<Snowflake> ret; - Bind(m_get_msg_ids_stmt, 1, id); - - while (FetchOne(m_get_msg_ids_stmt)) { - Snowflake x; - Get(m_get_msg_ids_stmt, 0, x); - ret.push_back(x); - } - - Reset(m_get_msg_ids_stmt); - - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching ids: %s\n", sqlite3_errstr(m_db_err)); - return ret; -} - -std::vector<Message> Store::GetPinnedMessages(Snowflake channel_id) const { - std::vector<Message> ret; - - Bind(m_get_pins_stmt, 1, channel_id); - while (FetchOne(m_get_pins_stmt)) { - Snowflake x; - Get(m_get_pins_stmt, 0, x); - auto msg = GetMessage(x); - if (msg.has_value()) - ret.push_back(*msg); - } - - Reset(m_get_pins_stmt); - - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching pins: %s\n", sqlite3_errstr(m_db_err)); - return ret; -} - -std::vector<ChannelData> Store::GetActiveThreads(Snowflake channel_id) const { - std::vector<ChannelData> ret; - - Bind(m_get_threads_stmt, 1, channel_id); - while (FetchOne(m_get_threads_stmt)) { - Snowflake x; - Get(m_get_threads_stmt, 0, x); - auto chan = GetChannel(x); - if (chan.has_value()) - ret.push_back(*chan); - } - - Reset(m_get_threads_stmt); - - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching threads: %s\n", sqlite3_errstr(m_db_err)); - return ret; -} - -std::optional<ChannelData> 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; - } - - ChannelData 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); - ret.RecipientIDs = nlohmann::json::parse(tmps).get<std::vector<Snowflake>>(); - } - 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); - if (!IsNull(m_get_chan_stmt, 18)) { - ret.ThreadMetadata.emplace(); - Get(m_get_chan_stmt, 18, ret.ThreadMetadata->IsArchived); - Get(m_get_chan_stmt, 19, ret.ThreadMetadata->AutoArchiveDuration); - Get(m_get_chan_stmt, 20, ret.ThreadMetadata->ArchiveTimestamp); - } - - Reset(m_get_chan_stmt); - - return ret; -} - -std::optional<EmojiData> Store::GetEmoji(Snowflake id) const { - Bind(m_get_emote_stmt, 1, id); - if (!FetchOne(m_get_emote_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching emoji: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_emote_stmt); - return std::nullopt; - } - - EmojiData ret; - ret.ID = id; - Get(m_get_emote_stmt, 1, ret.Name); - - if (!IsNull(m_get_emote_stmt, 2)) { - std::string tmp; - Get(m_get_emote_stmt, 2, tmp); - ret.Roles = nlohmann::json::parse(tmp).get<std::vector<Snowflake>>(); - } - - if (!IsNull(m_get_emote_stmt, 3)) { - ret.Creator = std::optional<UserData>(UserData()); - Get(m_get_emote_stmt, 3, ret.Creator->ID); - } - Get(m_get_emote_stmt, 4, ret.NeedsColons); - Get(m_get_emote_stmt, 5, ret.IsManaged); - Get(m_get_emote_stmt, 6, ret.IsAnimated); - Get(m_get_emote_stmt, 7, ret.IsAvailable); - - Reset(m_get_emote_stmt); - - return ret; -} - -std::optional<GuildData> Store::GetGuild(Snowflake id) const { - Bind(m_get_guild_stmt, 1, id); - if (!FetchOne(m_get_guild_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching guild: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_guild_stmt); - return std::nullopt; - } - - GuildData ret; - ret.ID = id; - Get(m_get_guild_stmt, 1, ret.Name); - Get(m_get_guild_stmt, 2, ret.Icon); - Get(m_get_guild_stmt, 3, ret.Splash); - Get(m_get_guild_stmt, 4, ret.IsOwner); - Get(m_get_guild_stmt, 5, ret.OwnerID); - Get(m_get_guild_stmt, 6, ret.PermissionsNew); - Get(m_get_guild_stmt, 7, ret.VoiceRegion); - Get(m_get_guild_stmt, 8, ret.AFKChannelID); - Get(m_get_guild_stmt, 9, ret.AFKTimeout); - Get(m_get_guild_stmt, 10, ret.VerificationLevel); - Get(m_get_guild_stmt, 11, ret.DefaultMessageNotifications); - std::string tmp; - Get(m_get_guild_stmt, 12, tmp); - ret.Roles.emplace(); - for (const auto &id : nlohmann::json::parse(tmp).get<std::vector<Snowflake>>()) - ret.Roles->emplace_back().ID = id; - Get(m_get_guild_stmt, 13, tmp); - ret.Emojis.emplace(); - for (const auto &id : nlohmann::json::parse(tmp).get<std::vector<Snowflake>>()) - ret.Emojis->emplace_back().ID = id; - Get(m_get_guild_stmt, 14, tmp); - ret.Features = nlohmann::json::parse(tmp).get<std::unordered_set<std::string>>(); - Get(m_get_guild_stmt, 15, ret.MFALevel); - Get(m_get_guild_stmt, 16, ret.ApplicationID); - Get(m_get_guild_stmt, 17, ret.IsWidgetEnabled); - Get(m_get_guild_stmt, 18, ret.WidgetChannelID); - Get(m_get_guild_stmt, 19, ret.SystemChannelFlags); - Get(m_get_guild_stmt, 20, ret.RulesChannelID); - Get(m_get_guild_stmt, 21, ret.JoinedAt); - Get(m_get_guild_stmt, 22, ret.IsLarge); - Get(m_get_guild_stmt, 23, ret.IsUnavailable); - Get(m_get_guild_stmt, 24, ret.MemberCount); - Get(m_get_guild_stmt, 25, tmp); - ret.Channels.emplace(); - for (const auto &id : nlohmann::json::parse(tmp).get<std::vector<Snowflake>>()) - ret.Channels->emplace_back().ID = id; - Get(m_get_guild_stmt, 26, ret.MaxPresences); - Get(m_get_guild_stmt, 27, ret.MaxMembers); - Get(m_get_guild_stmt, 28, ret.VanityURL); - Get(m_get_guild_stmt, 29, ret.Description); - Get(m_get_guild_stmt, 30, ret.BannerHash); - Get(m_get_guild_stmt, 31, ret.PremiumTier); - Get(m_get_guild_stmt, 32, ret.PremiumSubscriptionCount); - Get(m_get_guild_stmt, 33, ret.PreferredLocale); - Get(m_get_guild_stmt, 34, ret.PublicUpdatesChannelID); - Get(m_get_guild_stmt, 35, ret.MaxVideoChannelUsers); - Get(m_get_guild_stmt, 36, ret.ApproximateMemberCount); - Get(m_get_guild_stmt, 37, ret.ApproximatePresenceCount); - Get(m_get_guild_stmt, 38, ret.IsLazy); - Get(m_get_guild_stmt, 39, tmp); - ret.Threads.emplace(); - for (const auto &id : nlohmann::json::parse(tmp).get<std::vector<Snowflake>>()) - ret.Threads->emplace_back().ID = id; - - Reset(m_get_guild_stmt); - - return ret; -} - -std::optional<GuildMember> Store::GetGuildMember(Snowflake guild_id, Snowflake user_id) const { - Bind(m_get_member_stmt, 1, user_id); - Bind(m_get_member_stmt, 2, guild_id); - if (!FetchOne(m_get_member_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching member: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_member_stmt); - return std::nullopt; - } - - GuildMember ret; - ret.User.emplace().ID = user_id; - Get(m_get_member_stmt, 2, ret.Nickname); - std::string tmp; - Get(m_get_member_stmt, 3, tmp); - ret.Roles = nlohmann::json::parse(tmp).get<std::vector<Snowflake>>(); - Get(m_get_member_stmt, 4, ret.JoinedAt); - Get(m_get_member_stmt, 5, ret.PremiumSince); - Get(m_get_member_stmt, 6, ret.IsDeafened); - Get(m_get_member_stmt, 7, ret.IsMuted); - Get(m_get_member_stmt, 8, ret.Avatar); - Get(m_get_member_stmt, 9, ret.IsPending); - - Reset(m_get_member_stmt); - - return ret; -} - -std::optional<Message> Store::GetMessage(Snowflake id) const { - Bind(m_get_msg_stmt, 1, id); - if (!FetchOne(m_get_msg_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching message: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_msg_stmt); - return std::nullopt; - } - - auto ret = GetMessageBound(m_get_msg_stmt); - - return std::optional<Message>(std::move(ret)); -} - -std::optional<PermissionOverwrite> Store::GetPermissionOverwrite(Snowflake channel_id, Snowflake id) const { - Bind(m_get_perm_stmt, 1, id); - Bind(m_get_perm_stmt, 2, channel_id); - if (!FetchOne(m_get_perm_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching permission: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_perm_stmt); - return std::nullopt; - } - - PermissionOverwrite ret; - ret.ID = id; - uint64_t tmp; - Get(m_get_perm_stmt, 2, tmp); - ret.Type = static_cast<PermissionOverwrite::OverwriteType>(tmp); - Get(m_get_perm_stmt, 3, tmp); - ret.Allow = static_cast<Permission>(tmp); - Get(m_get_perm_stmt, 4, tmp); - ret.Deny = static_cast<Permission>(tmp); - - Reset(m_get_perm_stmt); - - return ret; -} - -std::optional<RoleData> Store::GetRole(Snowflake id) const { - Bind(m_get_role_stmt, 1, id); - if (!FetchOne(m_get_role_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching role: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_role_stmt); - return std::nullopt; - } - - RoleData ret; - ret.ID = id; - Get(m_get_role_stmt, 1, ret.Name); - Get(m_get_role_stmt, 2, ret.Color); - Get(m_get_role_stmt, 3, ret.IsHoisted); - Get(m_get_role_stmt, 4, ret.Position); - uint64_t tmp; - Get(m_get_role_stmt, 5, tmp); - ret.Permissions = static_cast<Permission>(tmp); - Get(m_get_role_stmt, 6, ret.IsManaged); - Get(m_get_role_stmt, 7, ret.IsMentionable); - - Reset(m_get_role_stmt); - - return ret; -} - -std::optional<UserData> Store::GetUser(Snowflake id) const { - Bind(m_get_user_stmt, 1, id); - if (!FetchOne(m_get_user_stmt)) { - if (m_db_err != SQLITE_DONE) - fprintf(stderr, "error while fetching user info: %s\n", sqlite3_errstr(m_db_err)); - Reset(m_get_user_stmt); - return std::nullopt; - } - - UserData ret; - Get(m_get_user_stmt, 0, ret.ID); - Get(m_get_user_stmt, 1, ret.Username); - Get(m_get_user_stmt, 2, ret.Discriminator); - Get(m_get_user_stmt, 3, ret.Avatar); - Get(m_get_user_stmt, 4, ret.IsBot); - Get(m_get_user_stmt, 5, ret.IsSystem); - Get(m_get_user_stmt, 6, ret.IsMFAEnabled); - Get(m_get_user_stmt, 7, ret.Locale); - Get(m_get_user_stmt, 8, ret.IsVerified); - Get(m_get_user_stmt, 9, ret.Email); - Get(m_get_user_stmt, 10, ret.Flags); - Get(m_get_user_stmt, 11, ret.PremiumType); - Get(m_get_user_stmt, 12, ret.PublicFlags); - - Reset(m_get_user_stmt); - - return ret; -} - -void Store::ClearGuild(Snowflake id) { - m_guilds.erase(id); -} - -void Store::ClearChannel(Snowflake id) { - m_channels.erase(id); - Bind(m_clear_chan_stmt, 1, id); - - if ((m_db_err = sqlite3_step(m_clear_chan_stmt)) != SQLITE_DONE) - printf("clearing channel failed: %s\n", sqlite3_errstr(m_db_err)); - - Reset(m_clear_chan_stmt); -} - -void Store::ClearBan(Snowflake guild_id, Snowflake user_id) { - Bind(m_clear_ban_stmt, 1, guild_id); - Bind(m_clear_ban_stmt, 2, user_id); - - if ((m_db_err = sqlite3_step(m_clear_ban_stmt)) != SQLITE_DONE) - printf("clearing ban failed: %s\n", sqlite3_errstr(m_db_err)); - - Reset(m_clear_ban_stmt); -} - -const std::unordered_set<Snowflake> &Store::GetChannels() const { - return m_channels; -} - -const std::unordered_set<Snowflake> &Store::GetGuilds() const { - return m_guilds; -} -void Store::ClearAll() { - m_channels.clear(); - m_guilds.clear(); -} - -void Store::BeginTransaction() { - m_db_err = sqlite3_exec(m_db, "BEGIN TRANSACTION", nullptr, nullptr, nullptr); -} - -void Store::EndTransaction() { - m_db_err = sqlite3_exec(m_db, "COMMIT", nullptr, nullptr, nullptr); -} - -bool Store::CreateTables() { - const char *create_users = R"( - CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY, - username TEXT NOT NULL, - discriminator TEXT NOT NULL, - avatar TEXT, - bot BOOL, - system BOOL, - mfa BOOL, - locale TEXT, - verified BOOl, - email TEXT, - flags INTEGER, - premium INTEGER, - pubflags INTEGER - ) - )"; - - const char *create_permissions = R"( - CREATE TABLE IF NOT EXISTS permissions ( - id INTEGER NOT NULL, - channel_id INTEGER NOT NULL, - type INTEGER NOT NULL, - allow INTEGER NOT NULL, - deny INTEGER NOT NULL, - PRIMARY KEY(id, channel_id) - ) - )"; - - const char *create_messages = R"( - CREATE TABLE IF NOT EXISTS messages ( - id INTEGER PRIMARY KEY, - channel_id INTEGER NOT NULL, - guild_id INTEGER, - author_id INTEGER NOT NULL, - content TEXT NOT NULL, - timestamp TEXT NOT NULL, - edited_timestamp TEXT, - tts BOOL NOT NULL, - everyone BOOL NOT NULL, - mentions TEXT NOT NULL, /* json */ - attachments TEXT NOT NULL, /* json */ - embeds TEXT NOT NULL, /* json */ - pinned BOOL, - webhook_id INTEGER, - type INTEGER, - application TEXT, /* json */ - reference TEXT, /* json */ - flags INTEGER, - stickers TEXT, /* json */ - reactions TEXT, /* json */ - deleted BOOL, /* extra */ - edited BOOL, /* extra */ - pending BOOL, /* extra */ - nonce TEXT, - sticker_items TEXT /* json */ - ) - )"; - - const char *create_roles = R"( - CREATE TABLE IF NOT EXISTS roles ( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL, - color INTEGER NOT NULL, - hoisted BOOL NOT NULL, - position INTEGER NOT NULL, - permissions INTEGER NOT NULL, - managed BOOL NOT NULL, - mentionable BOOL NOT NULL - ) - )"; - - const char *create_emojis = R"( - CREATE TABLE IF NOT EXISTS emojis ( - id INTEGER PRIMARY KEY, /*though nullable, only custom emojis (with non-null ids) are stored*/ - name TEXT NOT NULL, /*same as id*/ - roles TEXT, /* json */ - creator_id INTEGER, - colons BOOL, - managed BOOL, - animated BOOL, - available BOOL - ) - )"; - - const char *create_members = R"( - CREATE TABLE IF NOT EXISTS members ( - user_id INTEGER NOT NULL, - guild_id INTEGER NOT NULL, - nickname TEXT, - roles TEXT NOT NULL, /* json */ - joined_at TEXT NOT NULL, - premium_since TEXT, - deaf BOOL NOT NULL, - mute BOOL NOT NULL, - avatar TEXT, - pending BOOL, - PRIMARY KEY(user_id, guild_id) - ) - )"; - - const char *create_guilds = R"( - CREATE TABLE IF NOT EXISTS guilds ( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL, - icon TEXT NOT NULL, - splash TEXT, - owner BOOL, - owner_id INTEGER NOT NULL, - permissions INTEGER, /* new */ - voice_region TEXT, - afk_id INTEGER, - afk_timeout INTEGER NOT NULL, - verification INTEGER NOT NULL, - notifications INTEGER NOT NULL, - roles TEXT NOT NULL, /* json */ - emojis TEXT NOT NULL, /* json */ - features TEXT NOT NULL, /* json */ - mfa INTEGER NOT NULL, - application INTEGER, - widget BOOL, - widget_channel INTEGER, - system_flags INTEGER NOT NULL, - rules_channel INTEGER, - joined_at TEXT, - large BOOL, - unavailable BOOL, - member_count INTEGER, - channels TEXT NOT NULL, /* json */ - max_presences INTEGER, - max_members INTEGER, - vanity TEXT, - description TEXT, - banner_hash TEXT, - premium_tier INTEGER NOT NULL, - premium_count INTEGER, - locale TEXT NOT NULL, - public_updates_id INTEGER, - max_video_users INTEGER, - approx_members INTEGER, - approx_presences INTEGER, - lazy BOOL, - threads TEXT NOT NULL /* json */ - ) - )"; - - const 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, - archived BOOL, /* threads */ - auto_archive INTEGER, /* threads */ - archived_ts TEXT /* threads */ - ) - )"; - - const char *create_bans = R"( - CREATE TABLE IF NOT EXISTS bans ( - guild_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - reason TEXT, - PRIMARY KEY(user_id, guild_id) - ) - )"; - - const char *create_interactions = R"( - CREATE TABLE IF NOT EXISTS message_interactions ( - message_id INTEGER NOT NULL, - interaction_id INTEGER NOT NULL, - type INTEGER NOT NULL, - name STRING NOT NULL, - user_id INTEGER NOT NULL, - PRIMARY KEY(message_id) - ) - )"; - - 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)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_permissions, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create permissions table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_messages, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create messages table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_roles, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create roles table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_emojis, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "faile to create emojis table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_members, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create members table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_guilds, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create guilds table: %s\n", sqlite3_errstr(m_db_err)); - 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; - } - - m_db_err = sqlite3_exec(m_db, create_bans, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create bans table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_exec(m_db, create_interactions, nullptr, nullptr, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to create message interactions table: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - return true; -} - -bool Store::CreateStatements() { - const char *set_user = R"( - REPLACE INTO users VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_user = R"( - SELECT * FROM users WHERE id = ? - )"; - - const char *set_perm = R"( - REPLACE INTO permissions VALUES ( - ?, ?, ?, ?, ? - ) - )"; - - const char *get_perm = R"( - SELECT * FROM permissions WHERE id = ? AND channel_id = ? - )"; - - const char *set_msg = R"( - REPLACE INTO messages VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_msg = R"( - SELECT messages.*, - message_interactions.interaction_id as interaction_id, - message_interactions.name as interaction_name, - message_interactions.type as interaction_type, - message_interactions.user_id as interaction_user_id - FROM messages - LEFT OUTER JOIN - message_interactions - ON messages.id = message_interactions.message_id - WHERE id = ? - )"; - - const char *set_role = R"( - REPLACE INTO roles VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_role = R"( - SELECT * FROM roles WHERE id = ? - )"; - - const char *set_emoji = R"( - REPLACE INTO emojis VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_emoji = R"( - SELECT * FROM emojis WHERE id = ? - )"; - - const char *set_member = R"( - REPLACE INTO members VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_member = R"( - SELECT * FROM members WHERE user_id = ? AND guild_id = ? - )"; - - const char *set_guild = R"( - REPLACE INTO guilds VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_guild = R"( - SELECT * FROM guilds WHERE id = ? - )"; - - const char *set_chan = R"( - REPLACE INTO channels VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ) - )"; - - const char *get_chan = R"( - SELECT * FROM channels WHERE id = ? - )"; - - const char *set_ban = R"( - REPLACE INTO bans VALUES ( - ?, ?, ? - ) - )"; - - const char *get_ban = R"( - SELECT * FROM bans WHERE guild_id = ? AND user_id = ? - )"; - - const char *clear_ban = R"( - DELETE FROM bans WHERE guild_id = ? AND user_id = ? - )"; - - const char *get_bans = R"( - SELECT * FROM bans WHERE guild_id = ? - )"; - - const char *set_interaction = R"( - REPLACE INTO message_interactions VALUES ( - ?, ?, ?, ?, ? - ) - )"; - - const char *get_last_msgs = R"( - SELECT * FROM ( - SELECT * FROM messages - WHERE channel_id = ? - ORDER BY id DESC - LIMIT ? - ) T1 ORDER BY id ASC - )"; - - const char *get_msg_ids = R"( - SELECT id FROM messages WHERE channel_id = ? AND pending = 0 ORDER BY id ASC - )"; - - const char *get_pins = R"( - SELECT id FROM messages WHERE channel_id = ? AND pinned = 1 ORDER BY id ASC - )"; - - const char *get_threads = R"( - SELECT id FROM channels WHERE parent_id = ? AND (type = 10 OR type = 11 OR type = 12) AND archived = FALSE - )"; - - const char *clear_chan = R"( - DELETE 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)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_user, -1, &m_get_user_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get user statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_perm, -1, &m_set_perm_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set permission statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_perm, -1, &m_get_perm_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get permission statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_msg, -1, &m_set_msg_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set message statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_msg, -1, &m_get_msg_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get message statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_role, -1, &m_set_role_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set role statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_role, -1, &m_get_role_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get role statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_emoji, -1, &m_set_emote_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set emoji statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_emoji, -1, &m_get_emote_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get emoji statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_member, -1, &m_set_member_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set member statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_member, -1, &m_get_member_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get member statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_guild, -1, &m_set_guild_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set guild statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_guild, -1, &m_get_guild_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get guild statement: %s\n", sqlite3_errstr(m_db_err)); - 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; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_ban, -1, &m_set_ban_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set ban statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_ban, -1, &m_get_ban_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get ban statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, clear_ban, -1, &m_clear_ban_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare clear ban statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_bans, -1, &m_get_bans_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get bans statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, set_interaction, -1, &m_set_msg_interaction_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare set message interaction statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_last_msgs, -1, &m_get_last_msgs_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get last messages statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_msg_ids, -1, &m_get_msg_ids_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get msg ids statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_pins, -1, &m_get_pins_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get pins statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, get_threads, -1, &m_get_threads_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare get threads statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - m_db_err = sqlite3_prepare_v2(m_db, clear_chan, -1, &m_clear_chan_stmt, nullptr); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "failed to prepare clear channel statement: %s\n", sqlite3_errstr(m_db_err)); - return false; - } - - return true; -} - -void Store::Cleanup() { - sqlite3_finalize(m_set_user_stmt); - sqlite3_finalize(m_get_user_stmt); - sqlite3_finalize(m_set_perm_stmt); - sqlite3_finalize(m_get_perm_stmt); - sqlite3_finalize(m_set_msg_stmt); - sqlite3_finalize(m_get_msg_stmt); - sqlite3_finalize(m_set_role_stmt); - sqlite3_finalize(m_get_role_stmt); - sqlite3_finalize(m_set_emote_stmt); - sqlite3_finalize(m_get_emote_stmt); - sqlite3_finalize(m_set_member_stmt); - 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); - sqlite3_finalize(m_set_ban_stmt); - sqlite3_finalize(m_get_ban_stmt); - sqlite3_finalize(m_clear_ban_stmt); - sqlite3_finalize(m_get_bans_stmt); - sqlite3_finalize(m_set_msg_interaction_stmt); - sqlite3_finalize(m_get_last_msgs_stmt); - sqlite3_finalize(m_get_msg_ids_stmt); - sqlite3_finalize(m_get_pins_stmt); - sqlite3_finalize(m_get_threads_stmt); - sqlite3_finalize(m_clear_chan_stmt); -} - -void Store::Bind(sqlite3_stmt *stmt, int index, int num) const { - m_db_err = sqlite3_bind_int(stmt, index, num); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error binding index %d: %s\n", index, sqlite3_errstr(m_db_err)); - } -} - -void Store::Bind(sqlite3_stmt *stmt, int index, uint64_t num) const { - m_db_err = sqlite3_bind_int64(stmt, index, num); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error binding index %d: %s\n", index, sqlite3_errstr(m_db_err)); - } -} - -void Store::Bind(sqlite3_stmt *stmt, int index, const std::string &str) const { - m_db_err = sqlite3_bind_blob(stmt, index, str.c_str(), str.length(), SQLITE_TRANSIENT); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error binding index %d: %s\n", index, sqlite3_errstr(m_db_err)); - } -} - -void Store::Bind(sqlite3_stmt *stmt, int index, bool val) const { - m_db_err = sqlite3_bind_int(stmt, index, val ? 1 : 0); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error binding index %d: %s\n", index, sqlite3_errstr(m_db_err)); - } -} - -void Store::Bind(sqlite3_stmt *stmt, int index, std::nullptr_t) const { - m_db_err = sqlite3_bind_null(stmt, index); - if (m_db_err != SQLITE_OK) { - fprintf(stderr, "error binding index %d: %s\n", index, sqlite3_errstr(m_db_err)); - } -} - -bool Store::RunInsert(sqlite3_stmt *stmt) { - m_db_err = sqlite3_step(stmt); - Reset(stmt); - return m_db_err == SQLITE_DONE; -} - -bool Store::FetchOne(sqlite3_stmt *stmt) const { - m_db_err = sqlite3_step(stmt); - return m_db_err == SQLITE_ROW; -} - -void Store::Get(sqlite3_stmt *stmt, int index, int &out) const { - out = sqlite3_column_int(stmt, index); -} - -void Store::Get(sqlite3_stmt *stmt, int index, uint64_t &out) const { - out = sqlite3_column_int64(stmt, index); -} - -void Store::Get(sqlite3_stmt *stmt, int index, std::string &out) const { - const unsigned char *ptr = sqlite3_column_text(stmt, index); - if (ptr == nullptr) - out = ""; - else - out = reinterpret_cast<const char *>(ptr); -} - -void Store::Get(sqlite3_stmt *stmt, int index, bool &out) const { - out = sqlite3_column_int(stmt, index) != 0; -} - -void Store::Get(sqlite3_stmt *stmt, int index, Snowflake &out) const { - const int64_t num = sqlite3_column_int64(stmt, index); - 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); -} |